{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 分类训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 机器学习中HELLO WORRD，每产生一个新的分类算法，都会在MNIST上进行测试，查看执行结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import struct   # 用于打包的模块\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b'\\x00\\x00\\x00\\x02'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 压缩\n",
    "struct.pack('>i',2)   # 高位字节， >i是指打包成的类型，目标是2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2051, 60000, 28, 28)\n",
      "47040000\n"
     ]
    }
   ],
   "source": [
    "# 解压\n",
    "import struct\n",
    "with open('./MNIST_data/train-images-idx3-ubyte','rb') as f:\n",
    "    buffer = f.read(4*4)  # 4个int,具体查看解压文档，这四个int分别式是魔法数组，总的图片数，每个图片的行数和列数\n",
    "    head = struct.unpack('>iiii',buffer) \n",
    "    print(head)\n",
    "    length = head[1] * head[2] * head[3] # 【1】【2】【3】分别是图片的总个数，每个图片的行和列\n",
    "    print(length)\n",
    "    buffer = f.read(length)  # 拿到像素包\n",
    "    # print(buffer)\n",
    "    data = struct.unpack('>{}B'.format(length),buffer)  # 解包,B代表byte"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "47040000"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tuple"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 显示拿到的图片\n",
    "imgs = np.reshape(data,(head[1],head[2],head[3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000, 28, 28)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "imgs.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "for i in range(5):\n",
    "    plt.imshow(imgs[i],cmap = 'gray')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用.mat的方式加载数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\ProgramData\\Anaconda3\\lib\\site-packages\\sklearn\\utils\\deprecation.py:85: DeprecationWarning: Function fetch_mldata is deprecated; fetch_mldata was deprecated in version 0.20 and will be removed in version 0.22. Please use fetch_openml.\n",
      "  warnings.warn(msg, category=DeprecationWarning)\n",
      "D:\\ProgramData\\Anaconda3\\lib\\site-packages\\sklearn\\utils\\deprecation.py:85: DeprecationWarning: Function mldata_filename is deprecated; mldata_filename was deprecated in version 0.20 and will be removed in version 0.22. Please use fetch_openml.\n",
      "  warnings.warn(msg, category=DeprecationWarning)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import fetch_mldata\n",
    "mnist = fetch_mldata('MNIST original',data_home = './')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'DESCR': 'mldata.org dataset: mnist-original',\n",
       " 'COL_NAMES': ['label', 'data'],\n",
       " 'target': array([0., 0., 0., ..., 9., 9., 9.]),\n",
       " 'data': array([[0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        ...,\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mnist"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   * DESCR数据集描述\n",
    "   * data包含一个数组，每个实例为一行，每个特征为一列\n",
    "   * target包含一个带有标签的数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "X,y = mnist['data'],mnist['target']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000, 784)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000,)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "some_digit = X[36000] # 拿出第36000位的那张图片\n",
    "some_digit_image = some_digit.reshape(28,28)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(some_digit_image, cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.0"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[36000] # 查看该图片的标签"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 建立测试集和训练集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train,X_test,y_train,y_test = X[:60000],X[60000:],y[:60000],y[60000:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([58801,   885,  3726, ..., 53236, 58650,  6324])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将数据集合交叉洗牌，交叉验证时，每个子集合的数据分布均匀，有些机器学习算法对训练实例的顺序敏感\n",
    "shuffle_index = np.random.permutation(60000)  # 打乱里面的数据顺序，使其不具有连续性\n",
    "shuffle_index # 这里打乱的不是数据本身，而是它们的下标"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train,y_train = X_train[shuffle_index],y_train[shuffle_index]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       ...,\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([9., 0., 0., ..., 8., 9., 1.])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练一个二元分类器（只有两个结果，是或非）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False, ..., False, False, False])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 识别数字5， 二元分类5或非5\n",
    "# 创建目标向量\n",
    "y_train_5 = (y_train == 5)\n",
    "y_train_5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False, False, False, ..., False,  True, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       ...,\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False]])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_5.reshape(20,-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test_5 = (y_test == 5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# SGD 梯度下降分类器，适合非常大的数据集，独立处理训练集数据，一次一个，适合在线学习\n",
    "from sklearn.linear_model import SGDClassifier\n",
    "\n",
    "sgd_clf = SGDClassifier(random_state = 42)\n",
    "sgd_clf.fit(X_train,y_train_5)\n",
    "\n",
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 性能考核"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用交叉验证测量精度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.96515, 0.96305, 0.96465])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 评估分类器比评估回归器要困难的多\n",
    "\n",
    "# 3个折叠，正确率达到95%以上\n",
    "from sklearn.model_selection import cross_val_score\n",
    "cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring='accuracy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义一个估算器，把每张图片都分类为  非5\n",
    "from sklearn.base import BaseEstimator\n",
    "class Never5Classifier(BaseEstimator):\n",
    "    def fit(self,X,y=None):\n",
    "        pass\n",
    "    def predict(self,X):\n",
    "        return np.zeros((len(X), 1),dtype=bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False],\n",
       "       [False],\n",
       "       [False],\n",
       "       ...,\n",
       "       [False],\n",
       "       [False],\n",
       "       [False]])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.zeros((len(X), 1),dtype=bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.9113 , 0.9086 , 0.90905])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "never_5_clf = Never5Classifier()\n",
    "cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 准确率超过90% ，因为5的图像大约只有10%，你猜一张图不是5， 90%的时间你都是正确的\n",
    "* 这说明准确率无法成为分类器的首要性能指标，特别是当你处理偏科数据集， 某些类比其他类更为频繁"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 混淆矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 评估分类器性能的更好方法是混淆矩阵\n",
    "# A类别实例被分为B类别次数\n",
    "# 想要知道分类器将数字3和数字5混淆多少次，通过混淆矩阵的5行3列\n",
    "from sklearn.model_selection import cross_val_predict\n",
    "\n",
    "y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 与 cross_val_score 相比\n",
    "* 同样执行交叉验证\n",
    "* 返回的不是评估分数，是每个折叠的预测\n",
    "* 每一个实例在模型预测时使用的数据，在训练期间从未见过"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[53958,   621],\n",
       "       [ 1522,  3899]], dtype=int64)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "confusion_matrix(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 行表示实际类别，列表示预测类别\n",
    "# 第一行 第一列 53958 被正确的分为 非5 ，真负类\n",
    "# 第一行 第二列 621 被错误的分类成 5 ，假正类\n",
    "# 第二行 第一列 1522 张被错误的分为 非5， 假负类\n",
    "# 第二行 第二列 3899 张被正确的分在了5 ，真正类\n",
    "# 这种衡量方式太复杂，我们可以用更简单的指标"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[54579,     0],\n",
       "       [    0,  5421]], dtype=int64)"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_perfect_predictions = y_train_5\n",
    "confusion_matrix(y_train_5, y_train_perfect_predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 正类预测的准确率 被称为分类器的精度\n",
    "\n",
    "\n",
    "$\n",
    "\\text{精度} = \\cfrac{TP}{TP + FP}\n",
    "$\n",
    "\n",
    "TP是真正类的数量，FP是假正类的数量\n",
    "\n",
    "\n",
    "\n",
    "$\n",
    "\\text{召回率TPR} = \\cfrac{TP}{TP + FN}\n",
    "$\n",
    "* 检测正类实例的比例\n",
    "FN是假负类的数量\n",
    "<img src=\"./s1.PNG\" width = \"500\" height = \"300\" alt=\"图片无法加载时显示的文字\" align=center />\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 精度和召回率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8626106194690265"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import precision_score, recall_score\n",
    "\n",
    "precision_score(y_train_5, y_train_pred) # 4327 / 4327 + 1276   ，精度分数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7192399926212876"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred)    #  4327 / 4327 + 1094   ，召回分数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 说明 检测一张图的时候，只有86%的概率是准确的，而且只有71%的数字5 被它检测出来\n",
    "# 精度和召回率合成单一指标，成为 F1 分数，谐波平均值\n",
    "# 平均值平等对待所有的值，谐波平均值会给予较低值更高的权重，只有召回率和精度都很高时，才能获得较高的F1分数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\n",
    "F_1 = \\cfrac{2}{\\cfrac{1}{\\text{precision}} + \\cfrac{1}{\\text{recall}}} = 2 \\times \\cfrac{\\text{precision}\\, \\times \\, \\text{recall}}{\\text{precision}\\, + \\, \\text{recall}} = \\cfrac{TP}{TP + \\cfrac{FN + FP}{2}}\n",
    "$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.784428125943064"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import f1_score\n",
    "f1_score(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "# F1分数对那些具有相近精度和召回率的分类器更有利，这不一定符合你的期望\n",
    "# 有时候你更关心精度，有时你能关心召回率\n",
    "# 训练一个分类器检测儿童可以放心观看的视频，你可能要求拦截了很多正常的视频，即低召回率，保留下来的都是安全的视频，即高精度\n",
    "# 不能同时增加精度并减少召回率，反之亦然"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 精度/召回率权衡"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"./s2.PNG\" width = \"500\" height = \"300\" alt=\"图片无法加载时显示的文字\" align=center />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* SGDClassifier对每个实例基于决策函数计算一个分值，大于阀值为正类，否则为负类\n",
    "* 中间阀值右侧找到4个真正类 真5 ， 一个假正类 6， 精度为 4/5 80%\n",
    "* 在所有的6个 真正的5 中，分类器找到了4个，召回率为 4/6 67%\n",
    "* 提高阀值，向右移动，精度提高，召回降低\n",
    "* 反之阀值降低，召回提高，精度降低\n",
    "* SKlearn不可以直接设置阀值，可以访问决策分数，\n",
    "* SGDClassifier 默认阀值为0 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 如何设置阀值\n",
    "\n",
    "# 用predict_proba得到每个实例属于正类的概率，然后对概率切一下。以LogisticRegression为例\n",
    "# clf = LogisticRegression()\n",
    "# clf.fit(X_train, y_train)\n",
    "# pred_proba = clf.predict_proba(X_test)[:, 1]\n",
    "# threshold = 0.75  # 阀值设置为0.75\n",
    "# pred_label = pred_proba > threshold\n",
    "\n",
    "# pred_proba是每个实例为真的概率\n",
    "# 假设阈值是0.75\n",
    "# pred_label里True就是概率大于0.75的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4730.49312129])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 返回决策值decision_function\n",
    "y_scores = sgd_clf.decision_function([some_digit])\n",
    "y_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "threshold = 0\n",
    "y_some_digit_pred = (y_scores > threshold)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 提高阀值可以降低召回率，提高阀值到200000，就错了这个图\n",
    "threshold = 200000\n",
    "y_some_digit_pred = (y_scores > threshold)\n",
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 如何决定使用什么阀值\n",
    "# 返回决策值，而不是预测结果\n",
    "y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3,\n",
    "                             method=\"decision_function\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000,)"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 有了y_scores，可以计算所有可能的阀值的精度和召回率\n",
    "y_scores.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import precision_recall_curve\n",
    "\n",
    "precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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+/bk5uayePHiivWRhqk3bNjAJZdcQrt27WjVqhWjR49m+fLlVeqEtrVx40YmTZpE69at6dOnD7Nnz67RbmkcqS1S6dq6Kw7HlsIvOOkkmDQpct333vPuV65suvaJSDMMY7Pot7lzK+vNnVt73XCnnRa93tSplfXeeadx9mnLli2kpKRUTHLy2muvcf/993PHHXewfPlyTjnlFEpLSxk/fjx//OMf+f73v8/LL7/Mddddx89//nNuvvnmitfas2cPZ5xxBgsWLOBHP/oRy5Yt45577qGkpCTqHN/z589nxowZTJkyhWXLljF//nwuv/xydu+OfmH67du3c+aZZ7JmzRoeeeQRFi5cSLt27Zg0aRIvR7g23yWXXMK5557LkiVLuPjii7njjjv4U7QTXiXmerXxjsx6f8tWPvoIPvwwcr1L/emrv/71JmqYiAAapo6LsrIySktLOXDgAAsXLuSFF17gP/7jP8jMzAS8QH3nnXfo1q1bxXOefvpp3njjDV5//XXOOussAM477zwA7rzzTm655Ra6dOnCAw88wObNm8nLy2PEiBEVz58yZUrU9qxatYpTTjmFmTNnVpRNnDix1n24//772bNnD6tWraoYcp84cSJDhgzh9ttv58ILL6xSf8aMGXznO98BYNy4cbz66qs8++yzFWXSuLq27grApi+86UVDvw1X17MnHDoErVo1VctEBJphz9i56LfwXuzUqbXXDffOO9Hrhfe2TzstNvswaNAg0tLS6NChAzfddBNXXXUVTzzxRMX60aNHVwligOXLl9OnTx/OOOMMSktLK24XXHABJSUlrF69GoBXXnmFkSNHVgniuowcOZL333+f6dOn8/e//53Dhw/X+Zx//vOfjB49uiKIAVJSUpgyZQrvv/8++/fvr1J/UrVx0aFDh/L555/Xu41yfDpndgbg43wvjA8ejF43M7Pm6JGINC71jONg8eLF5OTkkJ2dTZ8+fWpclah79+41nlNQUMBnn31GWpQJg3f5cxfu2rWLYcOGNag911xzDcXFxTz++OPMmTOHtLQ0Jk6cyP3330/fvn0jPmf37t0RA79bt24459izZw9t2rSpKO/QoUOVehkZGZp3ugl1yeoCwKYdXwLRh6lFJD4UxnEwdOjQKj3K6iKdA9yxY0f69evHwoULIz4nFJqdOnViWwOnTzIzrr/+eq6//nr2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\n",
      "text/plain": [
       "<Figure size 576x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 使用matplotlib 绘制精度和召回相对于阀值的函数图\n",
    "def plot_precision_recall_vs_threshold(precisions, recalls, thresholds):\n",
    "    plt.plot(thresholds, precisions[:-1], \"b--\", label=\"Precision\", linewidth=2)\n",
    "    plt.plot(thresholds, recalls[:-1], \"g-\", label=\"Recall\", linewidth=2)\n",
    "    plt.xlabel(\"Threshold\", fontsize=16)\n",
    "    plt.legend(loc=\"upper left\", fontsize=16)\n",
    "    plt.ylim([0, 1])\n",
    "\n",
    "plt.figure(figsize=(8, 4))\n",
    "plot_precision_recall_vs_threshold(precisions, recalls, thresholds)\n",
    "plt.xlim([-700000, 700000])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "def plot_precision_vs_recall(precisions, recalls):\n",
    "    plt.plot(recalls, precisions, \"b-\", linewidth=2)\n",
    "    plt.xlabel(\"召回\", fontsize=16)\n",
    "    plt.ylabel(\"精度\", fontsize=16)\n",
    "    plt.axis([0, 1, 0, 1])\n",
    "\n",
    "plt.figure(figsize=(8, 6))\n",
    "plot_precision_vs_recall(precisions, recalls)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 通过选择阀值来实现最佳的精度/召回率权衡"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 目标设定为90%的精度，阀值大概在1500左右 , 设置了阀值为1500\n",
    "y_train_pred_90 = (y_scores > 1500)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9038112522686026"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "precision_score(y_train_5, y_train_pred_90)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.643054786939679"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred_90)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "* 获得了一个90%精度的分类器，但如果召回太低，精度再高，也不怎么有用\n",
    "* 如果工作中，需要99%的精度，你应该回应，召回率是多少？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ROC 曲线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 本质是 真正类率tpr和假正类率fpr（错误的分为正类的负类实例比例）\n",
    "# 与召回/精度曲线非常相似"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import roc_curve\n",
    "\n",
    "fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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yJIlS1T4chDXlf43W3KA4I124mO0776IuJ+1lueee47MzExuv/128vLyAPB69W+gHMx1pb9hd3D7Xe3EJyKRIDs7m6FDhzJmzBi6devG8uXLSUrSv39SPted01/0/U4AjkvV1L6IuFtxcTFdunRh7dq13HPPPdx0000a3csRua701+4MTmslxrjujyYiAgSn840xxMbGMn78eE4//XTOOussp2NJHeC66f2yW0a0TtPGPCLiPtu2beP888/nnXfeAeDaa69V4Uulua70d+cFN+ZJT9H0voi4y/z588nIyGDRokXs2rXL6ThSB7mq9K215BX7AF2uJyLuUVJSwk033cSAAQNIS0tj+fLl2mxHjoqrSn9HbvAa/aTYKOonRDucRkSkerz++uvcf//9XHvttSxbtoz27ds7HUnqKFetdvtpZ/ByvbLRvohIXfbzzz9z/PHHc9lll/Hpp5/q3L0cM1eN9LMLSwE4rblutCMidVd+fj5XXnkl7du3Z926dRhjVPhSLVw10t8Turteu2YqfRGpm7788kuGDBnCDz/8wG233UaLFi2cjiQu4qqR/u7QvvupCTEOJxERqbpHH32Url27kpOTw4IFC5g2bRpRUa4am4nDXFX6yzbsBSAtOdbhJCIiVffVV1/Rr18/srKy6NOnj9NxxIVc9SNkvbjgHydgbQVHiojUDosWLaJevXqcccYZPPLII0RHR2OMcTqWuJSrRvplC/naNEl2OImIyJH5fD7uuOMO+vTpw8SJEwGIiYlR4UuNctVIf8m6PQA00Dl9EanFNm7cyLBhw/j4448ZOXIkjz76qNORJEK4qvRT4qPZkVtMUpyr/lgi4iJff/01PXv2pLS0lBdffJHhw4c7HUkiiKum9wtL/QA0StRCPhGpndq2bcvgwYNZuXKlCl/CzjWl7/MHyC3yYQwa6YtIrbJ69WrOP/98du3aRVRUFE888QRt2rRxOpZEINeU/t6C4CK+pNgovB4thBER51lree6558jMzGTFihWsXbvW6UgS4VxT+vsKgrvx5RZp330RcV52djZDhw5lzJgxdO/enaysLLp27ep0LIlwrin9naHd+M48IdXhJCIiMGHCBP79739zzz33MH/+fJo1a+Z0JBH3rN7fF5reT9HleiLikEAgQHZ2Nqmpqdx9992MHj2a7t27Ox1LZD/XlH7ZzXZSE6Id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zeWPf/wjL774Ij179mTWrFlORxIRF6lM6ccAcdbaci/HM8GTi/9HcHX/LOAOY0y0tba0nGN/D3ittd2NMTOMMW2stWsO874PUIU79mnxvtR169ato3///vz0009MmTKFiRMn4vWGbUdrEYkAlSn9x/hl173yxBEc7cdaa7cZY/qUV/ghvYFXQo/nE9zd71elb4zpA+QD2yoKV7aQT9P7Utelp6dz6qmn8txzz9GzZ0+n44iIC1U4PrbWPmitLT7C5wuBVsD20MdfHOHlEoHNocd7KOc2vMaYGGAScMvhXsQYc40xZrkxZnnZ9L4W8kldtHPnTsaOHUt2djaxsbG88cYbKnwRqTHVMilurd1grS1vRf+h8vhlyj7pMO9/C/C4tXbfEd7vaWttprU2s+w5jfSlrlm4cCEZGRm88MILfP75507HEZEIEO4z4SsITukDZADryznmPOCPxpgPgY7GmGcr88Lae1/qCp/Px+233855551HvXr1WLp0qe6MJyJhUdnV+9XlNeBjY0w6cD4wxBgzzVo7sewAa+3+uU1jzIfW2jEVvajHoM1KpM646aabePDBB7nyyit5+OGHSUxMdDqSiESIsJa+tTbHGNOb4EY+/7DWbgOyjnB878q8rs7nS11QUlJCTEwMf/3rX+natSuDBw92OpKIRJiwX+hmrd1rrX0lVPjVQqUvtVlBQQFjx47loosuIhAI0Lx5cxW+iDjCFVe3q/Oltvr666/p0qULTz/9NJ06dSIQCDgdSUQiWLjP6dcIrdyX2sZay1NPPcX48eOpX78+8+fPp1+/fk7HEpEI54qRvqb3pbbJy8vjnnvuoVevXmRlZanwRaRWcMVIX50vtcWKFSvo0KEDycnJfPrppzRv3hyP9ogWkVrCFf8aaaQvTvP7/dx999107dqV+++/H4AWLVqo8EWkVnHFSF/n9MVJW7ZsYfjw4XzwwQcMHTqUG264welIIiLlckXpq/PFKQsXLmTw4MEUFBQwY8YMRo0apY2iRKTWckXp6x9ZcUpaWhonnXQSzz//PG3btnU6jojIEbnihOPO3MPeBFCk2v3www/8/e9/B6BDhw589tlnKnwRqRNcUfrp9eOcjiARYtasWXTq1IkHHniALVu2AJppEpG6wxWl79FJfalhubm5jBgxgj/84Q907tyZrKws0tPTnY4lIlIlrjinr0v2pCZZa+nTpw8rV65kypQpTJw4Ea/X63QsEZEqc0npO51A3CgQCGCMwRjDpEmTSElJoWfPnhV/oYhILeWO6X2N9KWa7dixg4suuohHH30UgN/+9rcqfBGp81xR+up8qU7vv/8+GRkZLFy4kJiYGKfjiIhUG5eUvlpfjl1paSm33XYb/fr1IzU1laVLlzJ27FinY4mIVBtXlL7O6Ut1WL58Offeey9XXXUVy5Yt4/TTT3c6kohItXLJQj61vhy91atXc+qpp9K9e3eysrLo0KGD05FERGqEK0b6mt6Xo1FQUMDYsWM57bTTWLJkCYAKX0RczSUjfacTSF3z9ddfM2TIEL755htuvvlmOnXq5HQkEZEa55LSV+tL5T377LPccMMN1K9fn/nz59OvXz+nI4mIhIUrpvc10peqyM7OplevXmRlZanwRSSiuKL0RSry6aefMm/ePADGjx/P22+/TZMmTRxOJSISXq4o/e+35zodQWopv9/PtGnT6NWrF5MmTcJai8fjweNxxV99EZEqccW/fB2a13c6gtRCmzdv5rzzzmPSpEkMGjSI999/X1d6iEhEc8VCPv1DLofavHkzGRkZFBYW8vzzz/OHP/xBf09EJOK5ovS1kE/KWGsxxpCens64ceMYMmQIbdu2dTqWiEit4IrpfYNaX+CHH36gZ8+erF69GmMMU6ZMUeGLiBzAFaWvNVmRzVrLzJkz6dSpE99++y1btmxxOpKISK3kirrU5jyRKzc3lxEjRjBq1CgyMzNZtWoVffv2dTqWiEit5IrSl8j14IMPMmfOHKZOncr7779P8+bNnY4kIlJruWQhn0b6kSQQCLBt2zbS09O5+eabGThwIF26dHE6lohIreeKkb5W70eOHTt2cNFFF9GjRw/y8vKIjY1V4YuIVJIrRvq6/joyvP/++wwfPpy9e/cyffp0EhMTnY4kIlKnaKQvtZ7P5+O2226jX79+pKamsnTpUq6//nr9sCciUkWuKH394+9uxhg+++wzxowZw7Jlyzj99NOdjiQiUie5YnpfI313+s9//sNZZ51F06ZNmTdvHnFxcU5HEhGp09wx0teOfK5SUFDANddcw6WXXsr9998PoMIXEakGrhjp+wIBpyNINfnqq68YMmQIq1ev5pZbbmHq1KlORxIRcQ1XlP6WfUVOR5BqMG/ePC655BLq16/Pu+++S79+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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "def plot_roc_curve(fpr, tpr, label=None):\n",
    "    plt.plot(fpr, tpr, linewidth=2, label=label)\n",
    "    plt.plot([0, 1], [0, 1], 'k--')\n",
    "    plt.axis([0, 1, 0, 1])\n",
    "    plt.xlabel('假正类率', fontsize=16)\n",
    "    plt.ylabel('真正类率', fontsize=16)\n",
    "\n",
    "plt.figure(figsize=(8, 6))\n",
    "plot_roc_curve(fpr, tpr)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.963028127236276"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算曲线下面积AUC，虚线是随机分类0.5到1\n",
    "from sklearn.metrics import roc_auc_score\n",
    "\n",
    "roc_auc_score(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 召回率TPR越高，分类器的假正类FPR就越多\n",
    "* 虚线表示纯随机分类器的ROC曲线，好的分类器应该远离这条线，向左上角\n",
    "* 是使用精度/召回率 PR曲线，还是使用ROC，关键在于 正类非常少或者更关注假正类而不是假负类，选择PR，反之ROC\n",
    "* 例如：前面例子ROC曲线很不错是因为跟负类 非5 相比， 正类 数据5 数量真的很少"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练随机森林分类器，比较SGD分类器的ROC曲线和ROC AUC分数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 获取训练集中每个实例的分数\n",
    "* RandomForestClassifier 没有descision_function(),但是拥有dict_proda()方法，sklearn中分类器都有这两个中的一个\n",
    "* dict_proda返回一个矩阵，每行一个实例，每列代表一个类别的概率，比如这个图片 70%是5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "forest_clf = RandomForestClassifier(n_estimators=10, random_state=42)\n",
    "y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3,\n",
    "                                    method=\"predict_proba\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.9, 0.1],\n",
       "       [0.9, 0.1],\n",
       "       [0.9, 0.1],\n",
       "       ...,\n",
       "       [1. , 0. ],\n",
       "       [1. , 0. ],\n",
       "       [1. , 0. ]])"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_probas_forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 绘制ROC曲线，需要决策值不是概率，直接使用正类的概率作为决策值：\n",
    "y_scores_forest = y_probas_forest[:, 1] \n",
    "fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5,y_scores_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.1, 0.1, 0.1, ..., 0. , 0. , 0. ])"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_scores_forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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PP/88+zatcv7iI6OBmDv3r2UlpaSmJhY4fqlpaXs3bu3wjl+9atfXdT5+pNPPuHMmTOkpaV5q+bT0tI4d+4cBw8eBGDy5Mls3ryZwYMHM3v2bAoKChg8eHCd4vcnV9zpd/fxyAxVJTs7mxkzZhAeHs7atWsZNWqUby9qjLli1PcO+0oRHx9PfHw8o0ePZtGiRSQnJwPwzTffkJCQQKdOnZg4cSLz5s3j2Wefvej46oa/lZaW0qxZxXvHoKCgCq8rJ/Cy1+pp128IsbGxFX5YVFY+huqu379//4uOK9vnlVdeITY2tsK2sh9Ot912G3//+99Zv349OTk5jBw5kh//+McsWbKkfh/Gx1xxp+9rO3bsYPLkyQwcOJA9e/ZYwjfGNEpz585l165dbNy4EYDNmzeTn5/PunXrePDBB7n++uurrMWsnMjLxMTEcPz4ce9dL8A777zjfR4fH8/XX39d4a46JyeH8PBwevihivbaa6+lWbNmFZoKcnJyaNasGddee22Nx8fGxhISEkJxcbH3h1PLli355S9/yYkTJwB4+umnOXToENOmTWPlypUsWLCA7OzsCucJCwu7qPYkUFxxp//1P31z3qNHj9KxY0f69+/P+vXrGTp0aLVffmOMudINGDCAW265hUWLFjFs2DBvD/7s7Gzi4uJYunQpf/3rX2s9sc2IESPo2rUrP/rRj8jIyGDnzp2sWrWKLl26AHDDDTcwbNgwkpOTefrpp/nyyy95/PHHycjI8MscAVdffTWTJ09m2rRpnD59GlXl4YcfZsqUKd479UsJDw/noYceYtasWagqXbp0ISsrixMnThAVFQXARx99xMqVK3nyySdp0aIFa9asuWjYdkJCAseOHWP58uX07t2bbdu2MWfOHF985JrVp/fflfQIiYrVn/y6YXvvnz9/XhctWqTh4eH6/vvvN+i5jTFXNjf33ldV/ctf/qKA5ubmqqrqT3/6U23fvr1GRkZqWlqaTp06VWNjY7WkpMTbOz4/P997fFlv9zJ5eXmamJio4eHhmpCQoHPmzKnQe/+rr77SiRMnasuWLbVTp06amZmp58+fV1Wn935mZqaqqqampmpqaqqqqmZmZupNN91U4+erTe/94uJinT59ukZERGhERIROnz5di4uLq/08lZ09e1ZnzZqlHTt21NatW+vtt9+un332WYXPl5qaqp06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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 6))\n",
    "plt.plot(fpr, tpr, \"b:\", linewidth=2, label=\"SGD\")\n",
    "plot_roc_curve(fpr_forest, tpr_forest, \"Random Forest\")\n",
    "plt.legend(loc=\"lower right\", fontsize=16)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9914278387487507"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Rand 比SGD 好很多，ROC AUC的分数也高很多\n",
    "roc_auc_score(y_train_5, y_scores_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9844264093002851"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 再看一下 精度和召回率 也很高\n",
    "y_train_pred_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3)\n",
    "precision_score(y_train_5, y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8278915329275042"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "* 选择合适的指标利用交叉验证来对分类器进行评估\n",
    "* 选择满足需求的精度/召回率权衡\n",
    "* 使用ROC曲线和ROC AUC分数比较多个模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 多类别分类器\n",
    "* 尝试5 之外的检测\n",
    "* 多类别分类器 区分两个以上的类别\n",
    "* 随机森里和朴素贝叶斯可以直接处理多个类别\n",
    "* 支持向量机svm和线性分类器只可以处理二元分类器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 解决方案\n",
    "1. 将数字图片分类0到9，训练10个二元分类器，每个数字一个，检测一张图片时，获取每个分类器的决策分数，哪个最高属于哪个，称为一对多OvA\n",
    "2. 为每一对数字训练一个二元分类器，区分0，1 区分0，2 区分1，2 称为一对一OvO策略，存在N个类别，需要N*（N-1）/2个分类器，最后看哪个类别获胜最多\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 优缺点\n",
    "* OvO 只需要用到部分训练集对其必须区分两个类别进行训练\n",
    "* 对于较小训练集合OvO比较有优势， 大训练集合 OvA 速度快，所以OvA更常用，比如svm 在数据规模扩大时表现糟糕\n",
    "* sklearn 检查到使用二元分类算法进行多类别分类任务，会自动运行OvA，SVM分类器除外"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.fit(X_train, y_train)\n",
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-16725.38661749, -17788.62934678, -10416.97995741,\n",
       "         -4499.53302565, -14360.19772072,   4087.71000323,\n",
       "        -17803.96525346, -14332.67934742, -11879.57770963,\n",
       "        -13346.65622659]])"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 内部实际上训练了10个二元分类器，获得图片的决策分数，然后选择了分数最高的类别\n",
    "# 返回10个分数，每个类别1个\n",
    "some_digit_scores = sgd_clf.decision_function([some_digit])\n",
    "some_digit_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.argmax(some_digit_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 目标类别列表会存储在classes_这个属性中，按值大小排列，\n",
    "sgd_clf.classes_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.0"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.classes_[np.argmax(some_digit_scores)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用OvO策略，一对一或者一对多\n",
    "from sklearn.multiclass import OneVsOneClassifier\n",
    "ovo_clf = OneVsOneClassifier(SGDClassifier(max_iter=5, tol=-np.infty, random_state=42))\n",
    "ovo_clf.fit(X_train, y_train)\n",
    "ovo_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "45"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(ovo_clf.estimators_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用随机森林\n",
    "forest_clf.fit(X_train, y_train)\n",
    "forest_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 0., 0., 0., 0., 1., 0., 0., 0., 0.]])"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 随机森林直接将实例分为多个类别，调用predict_proba()可以获得分类器将每个实例分类为每个类别的概率列表\n",
    "forest_clf.predict_proba([some_digit])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 评估分类器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.86152769, 0.86104305, 0.8540281 ])"
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用交叉验证评估SGD的准确率\n",
    "cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.90296941, 0.89769488, 0.90288543])"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将输入进行简单缩放 ，可以得到准确率 90 %以上\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "scaler = StandardScaler()\n",
    "X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))\n",
    "cross_val_score(sgd_clf, X_train_scaled, y_train, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 错误分析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 项目流程\n",
    "1. 探索数据准备的选项\n",
    "2. 尝试多个模型\n",
    "3. 选择最佳模型并用GridSearchCV对参数进行微调\n",
    "4. 尽可能自动化\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 确定了一个相对合适的模型，进一步优化，分析其错误类型\n",
    "* 查看混淆矩阵\n",
    "* 使用cross_val_predict()进行预测\n",
    "* 调用confusion_matrix()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5594,    0,   14,    9,    7,   35,   32,    4,  227,    1],\n",
       "       [   1, 6412,   43,   20,    3,   46,    5,    8,  194,   10],\n",
       "       [  23,   29, 5277,   80,   76,   20,   58,   38,  348,    9],\n",
       "       [  26,   20,  116, 5231,    0,  214,   26,   39,  388,   71],\n",
       "       [  11,   12,   36,   11, 5230,    8,   34,   22,  325,  153],\n",
       "       [  30,   14,   26,  159,   50, 4483,   83,   17,  498,   61],\n",
       "       [  30,   16,   45,    2,   42,   86, 5569,    5,  123,    0],\n",
       "       [  23,   10,   50,   26,   43,   13,    5, 5717,  178,  200],\n",
       "       [  18,   63,   43,   85,    3,  126,   30,    8, 5434,   41],\n",
       "       [  28,   20,   26,   60,  122,   40,    1,  175,  353, 5124]],\n",
       "      dtype=int64)"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)\n",
    "conf_mx = confusion_matrix(y_train, y_train_pred)\n",
    "conf_mx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 使用matplotlib的matshow 函数来查看混淆矩阵的图像表示\n",
    "plt.matshow(conf_mx, cmap = plt.cm.gray)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 看起来不错，大多数图片都在主对角线上，说明它们被正确分类\n",
    "# 数字5 看起来比较暗，说明1. 数字5图片较少  2. 分类器在数字5上执行效果不如其他数字上好\n",
    "# 假设把焦点放在错误上，为取得错误率，而不是错误绝对值，需要将混淆矩阵中每个值除以相应类别中的图片数量\n",
    "\n",
    "row_sums = conf_mx.sum(axis=1, keepdims=True)\n",
    "norm_conf_mx = conf_mx / row_sums"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 用0填充对角线 只保留错误，重新绘制\n",
    "np.fill_diagonal(norm_conf_mx, 0)\n",
    "plt.matshow(norm_conf_mx, cmap=plt.cm.gray)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 每行代表实际类别，每列代表预测类别\n",
    "# 8，9列比较亮，说明许多图片被错误的分类为数字8，9\n",
    "# 类别8，9行也偏亮，说明数字8和9经常会跟其他数字混淆\n",
    "# 有些很暗，比如行1，大多数数字1都被正确的分类，一些和8混淆\n",
    "# 5和3是错误最多的"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 结论\n",
    "* 改进数字8和9的分类\n",
    "* 修正数字3和5的混淆"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 如何优化分类器\n",
    "* 尝试多收集这些数字的训练集\n",
    "* 开发一些新特征来改进分类器\n",
    "* 优化分类器算法\n",
    "* 使用pillow或opencv对图片预处理，让显示模型更突出\n",
    "* 分析单个错误"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAccAAAHBCAYAAAAcpXCvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOydeVxN+RvHP5cQKQmNJpE1RiUz1hlkxqCMXTQGMzIT2Wns+y772EbIGNtYJvsg20jGFiFZUhrZEkVF+/b9/XFe36d7b4tb3XNv4/d9v173Rfeezvfp3HO+y/N9ns+jYIxBIBAIBAJBDqX0bYBAIBAIBCUNMTgKBAKBQKCGGBwFAoFAIFBDDI4CgUAgEKghBkeBQCAQCNQQg6NAIBAIBGoYvOdzkechEORGoW8Dioh4ngWC3OT5PIuVo0AgEAgEaojBUSAQCAQCNcTgKBAIBAKBGmJwFAgEAoFADTE4CgQCgUCgxvuiVf/zWFhYAACcnJzQsWNHAIClpSV9/vjxY5w7dw7du3cHAJiZmaFOnToAACsrKx1bWzCxsbEAgDt37mD+/PkAgL///hvffPMNli1bBgBo1KiRrDasWLECEyZMAAAYGBjA19cXANCjRw9Z230fMTExAIDJkyfjxo0bCA4OzvO4gQMHYu3atQAAU1NTndknEPzX+euvvwAAx48fx4YNG3Dq1CkAoH71Q0Pxnqoc//nQ7xEjRgAAfHx8kJGRodHv8MHxwoUL+Pjjj2WzTVPi4uIwbtw4/PPPPwCAR48e5TrGw8MDAPDrr7/Kasu7d+9oIuHv7w8DA2l+NWXKFMyZMwelS5eWtf288PPzw+TJkwEAISEhMDQ0RIsWLQAALi4u4Pf477//jps3b+LKlSsAQMcUAZHKoQciIiLQoUMHAECTJk1w+PBhjX7v999/ByA9z9OmTUPdunXlMvGD4927dwCA2bNnw9vbGwCQkpIChUKBH3/8EQAwc+ZM1KxZU282aoE8n2etDY68w/n888/zPxljUCjy71f8/PwAAJ06ddK0WY3ZuHEjDS4A0LhxYwBA8+bNAQDp6ekAgKVLl8Lf3x8AsGfPHri6umrdFk148OABDhw4AABYu3YtoqOj6TMDAwOyv1y5cggMDESbNm0ASANWqVLyesvfvn0LAPjpp5/w559/0vuVK1fGokWLAABubm4oV66crHYEBAQAAL755hs0a9YMANCnTx9069YNtWrVynV8REQEPvvsM4wePRoAaPVdBD7owfHVq1fkiYiNjUVycjIAoFatWvDw8KDJo645efIkevbsST+vXr0aANCvX79cXoD4+HgAwN69ezFu3DgAQFpaGhwdHXHu3DkdWZw3ycnJ8PLyQnh4OACpn+FYW1vjzJkzJWIA//vvvzFx4kQAwM2bN+l99X78448/RkhICACpD9AG/J57/fo1AKBq1aoAgPLly2vl/GqIPEeBQCAQCDSCMVbQS2Pu3bvH7t27x+zt7VmpUqXyfCkUinw/s7CwYHFxcSwuLq4wzWqdrKwsZmZmxszMzNicOXP0ZoeHhwdTKBT0qlevHnN3d2fu7u7s4cOHdNyUKVOYQqFgw4cPZ8OHD9epjdnZ2Wzp0qVs6dKlzMzMjEFamTAArHHjxszT05N5enqykJAQWdr39/dn/v7+7ODBgxodHxAQwBQKBVu/fj1bv359cZp+33NTUl8F8ubNG/bmzRtWrVo1ZmlpySwtLVnDhg1zPaujRo1io0aNKuKlKx4LFy5kCxcuZIaGhvRsmJmZse3bt7Pt27ezQ4cOMVdXV1a1alVWtWpVBkDlObpx44Ze7GaMsfnz57P58+cze3t7FZucnZ2ZnZ0ds7OzYwqFgrm4uOjNxpCQEBYSEsKGDBnCKleurGInf/Xt2zfXe0uWLGFLliwpdHtDhw5lQ4cOZS9evKD3du/ezWxtbZmtrS31J02aNGFNmjTR+FkvJHk+L1obHDlxcXHs5s2b7ObNm2zv3r10sUNCQpidnV2uB6169eqsevXq7Nq1a9r4I4tNSkoKMzU1ZaampiwwMFBvduzZs4f17t2b9e7dmw0fPpwlJCTkeZyNjY3eBkdloqOj2eLFi+n7VB4oK1euzHbs2KE32zjdu3dnCoWCXb16lV29erU4p9L3ICfL4BgVFcWioqLYokWL2KNHj9ijR4/Y27dv2ebNm9nmzZuZk5MTMzQ0pNeZM2eKePmKzw8//MAsLCyYhYVFrgFQ+QWA9erVi/Xq1YvduHGDZWVl6dTOFy9esBcvXrAmTZpQn1ezZk22YsUK9u7dO/bu3TsWHx/P2rZty9q2bcuMjY3Z6dOndWqjMrVr12a1a9ema2ptbc2sra3Z1q1bWXR0NIuOjmYvXrxQuca2trb0WWEIDQ1lxsbGzNjYmJUqVYo1bNiQNWzYUKXvyOt16tQpdurUKW3+2Xk+L8KtKhAIBAKBOvmNmqyIK0d1UlNTmZ+fH/Pz82Nly5ZVWTXWrl2bBQcHs+DgYG00pRUOHz5MMxR9rhwLIjMzk/n4+DAfHx9Wrlw5ZmBgQD/ri/DwcLZr1y42YcIENmHChFyzvQkTJujNtlevXrFXr14xExMT1r59e22cUt8rQFlWjprA3fgKhYJ16tRJG6csMny14uXlRd4e9ZWji4sLS05OZsnJyTq378WLF8zBwYE5ODgwhUJBzwbvVxISElhCQgLr1KkT2duzZ0+d26kM33KwtrZmv//+u8pniYmJLDExkTVr1kzl2fbw8ChSW/7+/u9dJdra2rIdO3awyZMns8mTJzOFQsHMzc2Zubk5Cw0N1cafzJiu3KrKREREsIEDB+a55zhw4ECWkZFR3Ca0Tt++fZmjoyNzdHTUuQtGUw4cOKDSASxcuFCn7fOHZMeOHaxnz56sZ8+eed7YlSpVYpUqVWK9e/dmT5480amNnJiYGGZvb0/7PHfv3tXGafU9yOltcFy2bBndd0OHDtXGKYvNhQsXWIsWLViLFi0YAGZkZMR8fX2Zr6+v3mxKSEhgTZo0oWs1btw4lpGRQX1eYmIia9++PWvfvj1TKBSsc+fOrHPnzrLtzxeX0NBQcv0CYOXLl6c91Ddv3hTpnNOnT893UOR9cGZmpsrvmJiY0DE9evRgV65cYdevX2fXr18vzp8n3KoCgUAgEGiCLAo5+/btAwCMHTsWr169yvMYe3t7lRy5Tp06oUqVKnKYoxFcfebkyZPYu3cvAMieL1hYeC4Rz0EDgAoVKuhUoSIpKYnau3z5MkxMTAAADg4OePLkCfr06QNASrDn+ar6SBC+d+8eAKBDhw5ITEwEANy4cQP169fXuS0fEklJSZLLCUDbtm31asvt27cBAN26dUNCQgIAQKFQwNXVFREREQCkvOXjx48DALp06YJWrVqhXbt2stv27t073L59G+PHjwcAeHp6kmBGeHg4+vXrRypOLVu2xMqVKwEAn3zyiey2FQTP8U5PT8erV6+wY8cOAFIeOxcEcHBwwIYNG9CqVatitcXVtdSpU6cOtm7dCgAFioocPnwYx44do+u6bds2uie5Mlpx0PrgePDgQQwYMAAAkJ2dne9xU6ZMUfnZ1NQUY8eOBQBMnToVZcqU0bZpBcKT19++fUvCACWJd+/eUUIuF1wApImILu1dtWoVLl++DECS5Nu2bRsAwNzcXGc2FERmZiZOnDiBgQMHApAeNJ5kbWNjo0/TPggOHDhACeAHDhyAnZ0dAKBBgwZyJWjny/Xr1wFICf/KSem8YwVUE9YDAgJgbGyMr776CoA0YMk1wH/00Uc4duwYTSQNDAxw4cIFAICrqyuio6PRtWtXAJKYQe3atWWxA5AUttatWwdAEkJYsGCBymdcFm779u0krJGenp5LsIULj5w6dQrVqlUrtl2VK1emBUh2djZdAz8/P5XrkZ2dTQsCPtHlZGZmIjMzE4B0XRs0aAAAOHHiRLHFKrQuHxcREYHvvvsOQM7Ny7G1taVVRP369bF79+48V5aurq74448/Ctt0kbl9+zaaNm0KAPjuu++wfft2AChQzUdu7t27RzO1ly9f4qeffqLVrbGxMa3QNm3aRDMnXdC3b1+a8dWuXZsepho1aujMhrx4/vw5AEnKisuFAZICEr9W/v7+aNKkCT3kX331VVHlAT9ohZyC8PX1pUnakydP6P3WrVvjyy+/LI7qUKHZv38/AEkikD+rVlZWaN++PQwNDQEA9erVo+OfPn0KX19fUnjKyMgglR0uv6hteMc9b9480vRNSEjAgAEDaGIpl4cqKSkJAODs7EzqYIMGDaJ2//rrL7i5uZEKjTLKkwqOkZERAEk5R1sT8hUrVgAALl26RP+3trZWOSYoKIgUsNSxt7en7zgwMBDPnj2jc5w/fx6ARp4roZAjEAgEAoEmyCI8npWVBQA4f/48Hj16RHuJyrqIgDQjyEv82c7ODrdu3SpK0xoxZ84cEi3++uuvERERQfsSgYGBsLe3l63t98Fn3suXL6eVozrGxsa0F8BFwHVFcnIyPvvsMwBAaGgoaZj+888/Ol89Xrp0CQBw69YtjBw5UuUzruvKXWicCxcuqLhm1q9fDwBwd3cvjCv//3blCAAvXrwAIO3Tcy/CunXrEB8fD0dHRwDS6kJX8PsAABo2bAgzM7N8j3358iW5XadOnUr3yZkzZ0ifWJts3rwZADBs2DB6z9zcHBcvXiS3n1weKu6Vq1WrFlJTU+l9HlPRvn17NGrUiLa/mjZtii5dugCQVo4tWrSg57t///60nTN79mzMmTNHFpvzYvny5eStUGbOnDmYMmUKfYfh4eGYOXMmAOlv5Nc3KCjofRV48v4C8gtjZVoK/c6PkJAQ5uLiopL3yJU3Tp48KWfTzNDQMFfocJkyZViZMmVYr1692KJFi9iiRYv0ImXn5ubG3NzccuVrmZmZsYoVK7KKFSsyhULBypUrx8qVK8eSkpJ0buONGzfYjRs3WLVq1ej6tW/fnj1+/Fj2tr29vZm3tzerWrUqK1u2LCtbtiwzNzcnqbrLly+z169fkxSaOvHx8eyPP/5gf/zxB3N0dCT7p06dylJSUlhKSoomZug7JUNvqRz5ERAQwL788ktmYGDADAwM2J9//ilnc1ph6tSp9P1PmjRJljZSU1NZamoqmz9/PmvevDlr3rw5PdP8nn379q0sbfOUq08//ZTabNu2LQsKCmJBQUGMMUkykCsjFcSYMWPoHE5OTkVO3ygKq1evpv4ZAGvTpg1r06ZNnv0zf4b79+9P3+3w4cPflzYoUjkEAoFAINCI/EZNJtNMk6tVuLq6qqyMjI2N2fLly9ny5cvlaFaFGTNmsBo1arAaNWowW1tb1q5dOzZ48GA2ePBgldXk4MGDWXx8vOz2KMNXrZUqVaJE2L1797LXr1+zCxcusAsXLqhcN32sHDkHDx5UEXgeMGAAS09PZ+np6bK1OW/ePDZv3jxmY2PDJk6cyCZOnFhoTUfO27dv2cCBA9nAgQOZQqFgc+bM0VRsXt8rwBK3cuTwZ6ckaOm+j+TkZFanTh1Wp04dZmJiInvhg6ysLJaVlcWuX7/Opk6dSh6zhg0bssDAQK0rcnHviYWFBfUXR44cKdK5uC4xF39430pT21y6dIldunSJubu7a/Q9hYeHq/Tl58+fL+jwPJ8XnT5MZ86coc6I3xhc9unYsWPabq5AYmJiWExMDP2cmZnJMjMz2f79+0ltQ6FQMEdHR5J50iVhYWEqihqMMXbu3Dl27ty5EjM4MpbjYuVVOcaOHcvGjh2rk7a5C+XIkSPs33//Zf/++2+hz8EfNHNzc1a+fHlWvnx5TVRK9D3IldjBkd+X/4XBMTY2lllZWTErKyumUChYbGwsi42N1Vn7u3fvZrt372YKhYJ169aNdevWTavn56Lnyv1FYaU6nz9/zp4/f85q1qxJ51i2bJlW7ZSDixcvqgyO3377bUGH629wnDp1Kps6dWquklXVqlVjERERLCIiQltNaRUuiyZXiZ5z584xIyMjZmRkxGbPnp1LKkmd8ePHs/HjxzOFQkH7j/rQjMwLDw8PkpUqX748e/DggaztJSQksI4dO7KOHTuyEydOFPt8ynsqGlTs0PcgJwZHLbBq1Sqyt1KlSjovmXf48GF2+PBhkpcbN26cVs9/5MgRduTIEZXB0dPTk/YiNYHLQyqfQ9Pf1QaZmZksLS1N4+MfPnzIHj58yKytrXPFlRRAns+L2HMUCAQCgUANWbPHMzMzMX36dJJGUmf37t3FVjGQEy5H5O3tDUBKRenQoYPWzn/jxg0kJycDkGTrJk+enK/KyM6dOyntoFKlSpg2bRoAyK5KcuPGDUqsdXJyQtmyZfM8bsmSJfD19SWhgr/++guenp6y2bVy5UqS2nJycir2+aKioiRXiqDI3LlzR98mFIolS5bQ/5cvX/6+cH+tw5XEAKB69epaPz9P1Fe+r58+fVqgchknOjoaU6ZMwaFDh+i9o0ePAsgRA9AFQUFB+OGHH0iGz8rKCl988QUAkHQlT+W5d+8eCQlERkaqnIcrZhUGWQZHfkF9fHxw4sQJer9WrVpo2bIlAGmg4TlRJRUTExOMHz8ebm5uACSpNm0Ojsp8/PHHuQa6tLQ0AICXlxeWLFmCjIwMAFIeaF55P3LQvXt3Up9xdXXFrFmz8tR/NDExQbdu3VSku+QmL2WPwuLl5QVAkkLjWpGffvppsc/7/8adO3fQsWNH6jjl1gj18fHB1atXAeTkEmpCcHAwTaaio6NJXYXrAOuC+Ph4bNy4kSbGNWrUQI8ePWRrTzmP0tfXl3SHx40bl6/STf/+/REaGkq/27NnT3z99dey2Zgfe/fuRWhoqEqeKM9j5RN13g/w/lEdFxcXLFy4sNBtC7eqQCAQCARqaH3leOrUKUydOhUAEBYWBgAkBvv999/TZyUNrhMZFhZGuq7p6emkSSg3hw4dgoeHBypUqABAWslwJRI+I3J1dQUgKVToihEjRlB7e/fuxeHDh0nVqE6dOjTzvHz5Ms6cOUOzObkrhRgbG5PSxyeffEIKOdzVogn//PMPiZKXK1cO06dPBwCdatV+KKxevRovX74kgWu5V99LlixRqU5TEHyFtm7dOixbtoxWGra2tjh48CAA3VSO4cpMU6dOxcaNG6nN48ePo2HDhlpvr3LlygAkFbAzZ87Q+3zl6O7unq86D2MMJiYm5KZ0dXUlvVpd0qFDB6xdu1ZlVfjmzRuNfpevdDdt2kTXojBoRT4uKSmJ9sA2btxIf0jp0qUxYMAAWtIWUeRZFri79/Lly7h69SoCAwMBSC4P3sFbWlqiffv2cHBwACCJ9hblIufH/v37aV/u6dOn+R5nb2+PL7/8EkuXLgUAnVcs4RVUtm3bhjdv3iA9PT3P48qVK0f3waxZs2S1KTU1FYMGDQIgXUdeXWHYsGHo0qVLnvtHSUlJSE1NJQHo1atXIyUlBYD0t/HJhwb8X8vHKcNl4vr27Yv4+HiSjpQbc3NzKhawadMmkjnj8AoYR48epWf97t27AEAlq3h5Jl1w584dul95qarQ0FAAOYsHuQgKCiK3bVRUFL3PWG5xceXP+vfvr9MCEPmRlpZG5Q03btyY74KlatWq1Fd37dqVqjxpgBAeFwgEAoFAE4q1cuTL2x07dqhEJlpaWgIAfvnlF/Tu3bvYRsqBra0tgJzZJF8tDhgwAEOGDAEAWYSI1bl//z4AwNvbG1u3bqWgkEaNGuHHH38EIJVfKYy7UE4ePnyImzdvApA293lh69atW2PXrl2y1qVT5/HjxwCADRs2UOShQqFAxYoV8/zu7t+/T78DSCW3uGs2v5I4+SBWjpBqjHJh9xs3bmDixIkU4CQ33333HbnEK1asmMvlx8tSpaWlUe3BqlWrYtWqVWSz3B6Y1NRUChZaunQpBbYZGRlh165d6NatGwDdlMaLi4sDIAUvcbcyYwzHjx+n0lb9+vWj0l0VKlRApUqV9OJKLYj09HS8fPkyz88MDQ2LWmcyzy+gWIMjd6Eph0TXqFGD3KhFCZ8VCP4D/F8PjkFBQQCAhQsXUnWbyZMnY968eTrbr01JSaFJ2pAhQyi+AZD6HV6pAQBGjx4NADqptsMHnp07d2LlypW0XVKpUiV8+eWXAKR4AkGJIs/nuVh3Mp8JVahQATNmzAAg3ajaqBItEAhKJhMmTAAgBUVdvnwZgBSAo8tApvLly+Pzzz8HkLN3VxLgnomdO3eicePGsLGxASB5N3SdRykoHmLPUSAQCAQCNWQpdiwQfOD8X7tVBYIPDBGtKhAIBAKBJojBUSAQCAQCNcTgKBAIBAKBGmJwFAgEAoFADTE4CgQCgUCghhgcBQKBQCBQQwyOAoFAIBCo8X9bm4dXD1i/fj1WrlypormpTufOnQFIBUB/+OEHndhXkuDK/NeuXUO/fv2olJaDgwPOnj0LQKpu0rVrV1LFr1GjBunVCj5ceOWDNWvW5NII5TnUCoUCx48fBwAqNKxtuGxbbGwsHjx4gL59+wKQCuM2atQIgPTM29vbk67y0KFDdaJrKvhvIlaOAoFAIBCoIYtCTkxMDACQALkyvKhweHg4OnToQHXGuCivruB1/IyMjAqsa6aMQqHAqFGjAEi1AOXm/PnzACSh55CQEGzbti3XMXnZ3rNnTwDaETjesmULRowYAQDIzMws8FhlW0aOHEmVWqytrYttRwnjv7rc0KpCTmRkJBU1jo+PL3DlyHVQeZ1FbeLv7w93d3cAUtWYn376iVaO9vb25CW6e/cu5s2bh4sXLwIA/vzzT7i4uGjdnv8yISEhAIAXL17g3r17JO4eFRWlUjC5Y8eOOHXqVLHbS0hIACBVduJjAyB5qQBQMfWhQ4cCAOrVq1fsNvNA+8Lj+cHLtKxZs0blffWO/O7du9i+fTsA4MqVK7IX/VSmVClp0dywYUPcv3+fqoq3bNkSDx8+BCB9EY0bNybX0c6dO+Ht7Q0A+PHHH4ut8p+cnIxjx44BAAICAnDkyBGVz/mN8/btWygUinwHcPX3C3IRa8rVq1cBSBUN3jco5sX69ethYWEBQKp8LgcBAQEAAEdHR7oGVatWxY4dO1C1alU6jt+PBw8exKtXr+hY5fvR39+fiuAKNKNatWrYvXs3AGkit2rVqnwLYctJpUqVaAK2bt06tG/fXqUqB+fjjz/Gr7/+Sj8/e/ZMVyaWSJ48eYK4uDgcPXoUgFQ0/MGDBwCkcls2NjbkknZycoKjoyMA4MiRIyoDZVF5+PAhnJ2dAQD//vuvymd8YsWf8YMHDwKQitTLNEDmQpbB8datWxofy/eldF3dnj88QUFB+PHHH2kF6+/vjwEDBgCQlP8BYOLEiQCkwTEjIwOANGsu7uD4+vVrfPvttwAKrsoNSJ0+73h4rbq8MDc3x19//VUsuwAgMTERgFQPTxMqVKhAdeE48+bNAwCcPn2aKsZrE369lCcOsbGx6NKli8qqRfn/6pMM/v/Q0FAxOBYSIyMj2o/v3LkzGjVqhIiICADA/PnzVY7lVXvkoGnTpjh9+vR7j/P398fhw4fRq1cvAMCYMWNks6mkwfut06dPY/r06QCkSXRycjI+/vhjAEDfvn1VvFP169enPjAtLY2+08jISJw4caLYNm3atEllUOQLD3VP06ZNm8gL1qlTp1wDqVyIPUeBQCAQCNSQZeW4a9cuAMDy5cuxYMEC2rOysLCgAshnz56Fubk5Tp48CQA6rSCvTPny5eHu7o46deoAyO3TTktLU9k7/eijjwAAHTp0KHbbpUuXRs2aNQHkuELNzc0BSFWtu3fvDgBo27YtqlSpgn/++QcAMGfOnHzPOXToUHJnFgce0Td9+nRyoURERCA2NhalS5cGADRr1gy9e/cGIFXoVl8d8JVuampqse3Ji7Zt2wIABgwYQNcmMjISDRs2hJGRUa7jGjZsCEBaXfK/TaA92rZti6VLl+Z6f/HixbTC1DVXr16lVeWSJUswZswYLFq0CEDO1sqHTlRUFGbPng1AiiGoW7cuAKmv6NmzJ1q1apXv7/JVWt++fREZGQlAcm22aNGi2HaNHz+e7ov79+9TJLOVlZXKcXfv3qWVoza2jDSGMVbQSys4OTkxJycnZmNjwxQKBVMoFOyjjz5it27d0lYTshAbG8uGDBlCNpcpU4YdPXqUHT16VOttrVq1iq1atYpFRUWxqKioXJ8PHDiQlSpVKtdLoVCwUqVKsfHjx7Px48ezsLAwrdvGCQ8PZ97e3uzatWvs2rVrKp/98ssvZIv6a/DgwbLZxImJiWExMTEsKCiIJSUlFXgsv1bK9gYEBBSmufc9NyX1pXXu3r3L7t69y44fP84cHBxUvncvLy/m5eXF0tPT5Wg6XzIyMtjjx4/Z48ePWcWKFVnz5s1Z8+bN2aJFi2RvOyQkhIWEhLCbN2+yQ4cOsUGDBrFBgwaxqlWr0svMzIx5eHiwyMhIFhkZKbtNJ0+eZCYmJszExIRt2rRJo985cOAAa9asGbO0tGSWlpZs48aNMluZP507d6Z7atSoUXI0kefz8v8xdRIIBAKBoBDIXuzYx8cHo0ePBiC51/hyfM+ePXpzpb6Pe/fuAQB69+6NsLAwGBhI3ue5c+fKFnnJiYqKAgDs3buX3vP09Mw3WKdp06YYO3Ysvv/+e1ntUobfM0+ePCEX+pUrV/DXX3+p2FmpUiUAUiBEcYOXtIWfnx+6dOkCQPo7duzYAQDk7teQ/+tUDh54FRUVRVsO27dvh0KhgKWlJQApQlgfrtSkpCS4ubmRm33y5MkUba5N+vTpAyB3lCXvO3gAjHLUNHdnMsYQFBREkaDXrl3LM7pWW0RGRlLUZ179BLf12LFjWLJkCQDJldm9e3faKuFbErri3bt3AKSgqW3btuGzzz4DIPUlylsmWkJ3qRzK7N69WyXiMTg4GABw7tw5WFtblxiFCv7AT5w4EVu3bgUg7Team5vTzzzsWC6ePn1K+Vk8zwdAgWkcK1eupBBrXXD8+HH4+voCQJ55lxwzMzOKaNP3wMg7hkOHDmHXrl10LRs2bEh7pgLN4deza9euKu/PnDmT9ux1PTBOmzYNgHR/WlhYUCqS+v6VtrCxsQEAnDp1SpD0NfgAACAASURBVCVKmytE9ejRA5999hn1GXyfnlOrVi3cuXMHAHD06FFZ8y2tra3zzDVOS0vD5s2baSJ+8+ZNsnfKlCkUwa8PNmzYAECadJmYmNAgLcPAmC/CrSoQCAQCgTr5bUYyLW3gHzt2jFWrVo1Vq1aNAaDgFoVCwYYPH87i4uJYXFycNpoqFBkZGSwjI4MlJyez3377jdWqVYvVqlVLxT6FQsGOHz+uM5vOnj3LTE1NmampaZ5BN3m9LCwsWGBgoM5sbNWqVb62KNvp5OREwQmFDHbRCidOnGAnTpxg5ubmDJI7kSkUCpV7EADz8/Njfn5+hT29vgNr9BKQ4+/vn+sZbt++PWvfvj0bM2YMi4mJKW4TheLRo0fs0aNHzN7enpUvX56VL1+ejRkzhiUkJOjMhvXr1zN3d3fm7u7OkpOTqV9RJzU1le3YsYPt2LGD9ezZk5UqVYpZW1sza2trlpmZqTN7GWMsIiKCRUREsE8//ZQpFArm6urKXF1dWUhISL6/c+HCBbZ9+3a2fft29ubNG1nte/ToEd1fpUqVYps3b5a1PZbP8yL7niMAXLp0CQDw8uVLrFixQuU9LmrNk+HlJDk5GQCwYsUKHDp0CIDkSmAFJOBXrFiRpOLc3Nxkt5Eny69evRq3b98GAGRnZ6Np06aUkjB37lxy5TDG4OrqSkolctO6dWsEBgbm+Zn6deTu3itXrqB9+/bkjq1QoYJs9sXExGDx4sX45ZdfAOQWAeDXEJDcgzx1Jjo6ujDNlIy9gMJTpOf5xx9/BCCplMTHx1M6k7OzM1atWgUgZ39ZV6SlpeGTTz4BIO37DRkyBICUHlC9enVMnjwZgCRLWb9+fQCS4EjTpk11ZmNycjJmzpwJQHLpP3r0CID0nDRq1Aj79u0DkJM2JSd8D2/9+vUqcROLFy+GoaEhAKkvVN5DvXv3LuLi4vI8X8eOHTFhwgQA0nOuzT3T5cuXY9KkSQCkZ3bSpEn45ptvAABt2rTRWjtK5Pk862RwVIZrmjZt2hRhYWE6HRwvX74MAKTzqAzPKezTpw+p9uzevVtF0i0gIEClc9UXrq6uNNDocnCMjIxE69at8fLlyzw/L2iSAeSoIJ0/f77A3KqiwPV8hw0bhkOHDqkMiHww7t27N8kV8s+KKB/3fzM4Xrt2Dd26dQMgXeN69eqRLKS+chcBKUagYsWKud6vWLEiWrVqhcqVKwOQ9FM5ZcuWhYODA7777jsAkjSinLmOXl5etBeqDGMMP/zwA+zs7ABIQTu8/5MrMMff3x8A8NVXX6nYoVAoaP/U0NBQo8C0lJQUbNmyhfIenZ2dsWXLFgDQSo51UlIS2Xn9+nUAOWplxsbG+Pnnn/P8veHDhxd1TzLP51nsOQoEAoFAoIbO6znyGUCZMmXwnlWr1uHuFScnJ4oec3FxQevWrUn0XHnl069fP3Tu3JlqFk6aNIlWn/pk+fLlNCPm/nFdUKlSJdjZ2eHVq1f0Hq/KkJiYiAcPHhS4cuQC5nfv3tX6ynHx4sUAJPeVunYqT9fgmprKnwlt1YKJjY2lVTkgVdrR54qRU6FCBYSFhQGQ0sKUGThwIGrVqgVA0uXkXLp0CVevXiXN308//VR2T1B+z6Z6pPfgwYMBAI0bN4aLiwvdi2XLltWKK3Ht2rUApKhZnl7Spk0bTJw4kVawvG/WhJEjR9L2yqBBg2g1t3Xr1mKvfo2MjGh7acOGDdi/fz+tUmNjY0nrWr2vmTRpEm3lODs7U6UW7kUoLDp3q3Ls7e1x584dnbpVi4JyXlyVKlVUOgp98fTpUwrN1vWeY3x8PCnkGxkZ0bVJS0ujIsiANADywtA8j4ozduxYrFy5Ums2rVq1ih5O7irirtTr16/nm6OlPDjevXuX8s404P/GrXrv3j3a73n8+DEYY7RHNnHiRJ3m12qDnTt3YtCgQQCkbRM5+53k5GS8efMm3895qlNMTAztPz548EAl9c3AwIAGx+KI9/OJxIsXL7Se+rVhwwaMHDkSAHDy5El07NhRq+dXxtfXV0WOUnngvH//PklWKhQKElT//fff0a5du4KKWwi3qkAgEAgEmqBzt6rc8CjY/fv3q7zftGnTwqqgAMiJpgWkxPaSAHeR6Aoe2Tt//nyEh4fj66+/BqBaTLlixYqoUqUK/VzQjFnbrul27dpR1OmrV6/Qp08fKq9TkLKH8sqxEKvG/ys++eQTHD58GIBURDsyMpJUYIYNG4bQ0FAAkiuTR4+WVM6dO4fRo0fTPcEFN+SiQoUK5MEICgqiZ4KvrLjbD8gRMbh9+zYOHTpEnqAHDx5QME1x4NtGctTM/fzzz3W2taMulqDcp58/f56KJJw7d476mU6dOmH16tVUqF5TdD448mVvRkYGSpcuTWHE2uD06dN0w799+xYVKlQgX35R9pO2bNmiEu3G0wOKgqurK/1/wYIFAHL2QAuLTpXpkSM5xdNHPD09cx3z4sULPH78mGpJ/vrrr7ncqXyfN68IvuLw2Wef4dy5cwAKN8jpes/7vwpXODp27Bh69uxJFdvT09NJbiwqKgqbN2/WeV1WTeD3xrRp01CrVi34+fkByK1aIyfTpk2j6iCjR49Gx44d8cUXXwCQ9sT4hMPPzw9+fn5UdBgotLShzvHx8aF9RmNjY73Z4ejoSC7jlJQUkg3csmULnj59Wujz6XxwvHDhAgBpRtSkSRP07NlTa+c+cOAAFQJu1qwZdu/eTXqGmpKSkkIBHGPHjkVaWhqaNGkCoGgDLIcPsgqFgmzipXM0hfvWef6jvuAb4gMGDCBt1ejoaDx+/LjAgJxjx44BgCx7EoUZFPmKtyBZPkFuGjVqhAcPHtDkhg+MgCTzNXPmzEI/b3LB8/U2btxIQTlffPEFNm3ahOrVq+vcnvHjx1Mg25o1a7B27VrKDTUwMKCJJ99P4/mYS5cuLbGBYvfv3wcgffc8IE7bgXZF5d27d8V+tsWeo0AgEAgEauh85cijsgApVUKbcOUOQHKZ5CW2mxcpKSnkapk7d67Kyqxu3bokBFAc0dtx48YBkJb4Xl5eAABvb29S0Bg/fnyBvx8WFkYh9MpuVcaY7OHozZo1AyD59AFQCHd+SjkcLqZQs2ZN+Pr6onHjxjJaqTnchcUYK7Gz8pLKmjVrKOFb2S1dUlzUL1++hJeXF3k0Spcujblz5wIARo0apbcCx05OTlTMlxdfOHr0KADpmnJBg2+//RZNmzYloQLlffySxL///ksF31u1aoWffvpJzxZJcI9B9+7d6Tk3NDRE+/btC30unaRy8L0nX19fknnKzs7GsWPHKLhDGwQHB1PYc1JSElq2bElVF1xcXMiNkZ6eTq61p0+f4ujRo3QhgRwll+HDh2PhwoVaVYL38fHBsGHDcr1vaWmJWbNmoU6dOgBUlSzCwsLwzTff5CqPA0jBOcOGDZN1/4Tv2bzvu1JXyOF7q3KX+SoMMTExVDbt8ePHNCnq1KlTYU7zX/XF5vk8b9++nUpPvY/w8PA83VXOzs7YvHmzVhRSCoKnCymH8/v6+tL7p06dwuPHj2ngadOmDZWcExQPdQk6nqq1YcOGQuVIatsm3i96e3tj48aNAKQtE77/uW3btvdVGBGpHAKBQCAQaILWVo7cxaYcsdavXz/s2rWL6pZduXKFZp27d+9WieDUFjyU18XFhYJz3gdjjGz+9ttvaXVblKX4+3j9+jXZOGbMGMTGxpINCoUCJiYmAFQDTF68eEERgupkZWVp3UZ1uJYqT6rND+WVY82aNSk6j9f4k4vr16+jWrVqAEDKKPmhXuw4KCgIQI7Sj4Z8UCvHtWvXktv/vSdQ+o4tLS0pkpl7CeTi3LlzWLlyJaVqqacKcY9L27ZtMW7cOKqrKCgaUVFRiImJIbF0X19fnDx5EoDkqp41axZGjBihc7v8/f0p48HPzw8XLlzAjRs36HOeqtK8eXO6pzV4tuUVHuc+cnUpJ5WTMUbRTHv27HlvR1YcXr9+jSNHjlAHfe/ePZW9RD7wVa9eHa1bt6Z9tdatW8tmkzpXrlyhop7+/v5ITU2lwVIZdXelslAxrxgiJ3wAfvLkCebPn68ifcUrop8+fRqOjo5UpcHY2FilCroc8Gi5xo0bU55j06ZNMW3aNJV9WK5qtHjxYuzatYuucc+ePSkyuZCVQj6owTE4OBidO3fWSP1J+X7r1q2brM+wMrVr10ZkZCQNgj169KACAvb29rQ3V1L36PQNj5Tdvn077RVaWFggPj6e0q8ASUEIkKLPlWUiHRwcKE1u8ODBsrvPOXFxcXBzc6M4i7xUcPjf4+HhQdHSfLKsIcKtKhAIBAKBJuhk5chdHN26daM6a3LW9PuvEhYWBm9vbwCqM3S+cuTRt35+fkUWEPgQ4fl3QM61Ui5Zpf5/7rJWDsIqJB/UylHw4cO3ZSZOnKhStEA9uIpvnXz99ddo1KgRuSTl1EstiC1btmDo0KEU/KO8InR2doaDgwNMTU2L20zJqOcoEGib5ORkij6+ePEigJy0kwcPHtDg+Mknn2DKlCkUwVyMCZoYHAWCDwcxOAoEWkIMjgLBh4PYcxQIBAKBQBPE4CgQCAQCgRpicBQIBAKBQA0xOAoEAoFAoIYYHAUCgUAgUEMMjgKBQCAQqCEGR4FAIBAI1BCDo0AgEAgEanzwhc4SEhIAALdu3aL3Ll++jMzMTADApk2b8PTp03x/f+/evVovylwQXOT7t99+o1qDBw4cwPDhw/OtfFC2bFkqlioQCASFgYuNT5kyhYp/9+nTB126dNFbncaSgNYVcjw9PamESO3atbFt2zbSvps5c+Z7K95rk0GDBlGh3ufPn+d5TMWKFVGmTBkqjJmamqqiRq/rwfGff/4BgEJVqLe2toanpycAqUCzNgof8+/pl19+gY+PDwDgxx9/LPZ5dc2bN2+QlpYGQNJpPHr0KKKiogBIZdaKWF1AKORA6lS5TF9e8JJ02ixonhdxcXFUWeLixYsIDw8n3dzq1aujbNmyAIAZM2agW7dustqiDr/3Vq9eTUW/s7OzAeRoTt+8eVOnNqnD5RTPnz+vUgrM3d0dmzZt0otNycnJAIC7d+9i3rx5OHbsGH2mrJU8aNAgbNmyBQCKU9RaKOQIBAKBQKAJWnOrxsfHAwAuXLhABWQvXLiAatWqUQ3HCRMmUL2/rl274tdff9VW87lISkrCzZs3acVoZ2eHXr16AVBdlVlYWMDY2BhWVlYAJPcrr+mYlZWls3p1gFQlYtCgQYX+vcjISBw9ehQAMHTo0GKvHNPS0nD16lUA0uzs7NmzAEruyvHhw4c0+3748CHV8ASkoq1JSUn0f2Xi4uJ0VpfuvwyvnxcWFoazZ8/SKu3GjRs0wy9dujSys7ORkpJCv+fo6CibTfHx8fj9998BANOmTaN2TU1N0bZtW6riAICK9Lq6uiI0NBQ1a9aUzS5OTEwMtm3bhiVLlgCQ6styeCWM6OhoAFKfo6/izCkpKVTp4t9//6Xixp9//nlxVmLFIjg4GF27dgWQ88zybSMTExPaenr16hV27txJ3gAXFxet2qG1v567TgcNGkTlTXr06AEjIyMqr+Tm5kYlrfbv348RI0bA1tZWWyaoYGRkhAMHDlBB3K5duxY4aPA9SE9PT6SmpgIArKysqIiuLihbtiwaNmwIAFTcU1Pu3r0LQBrYuBupqJQrVw4tW7YEIBVk5tXXlR9wDt+viIyMRN26ddG/f3/6jN8T2nDzFsSQIUPIHa1eggdQdcMAOW4+XjVcoMqdO3dognHt2jWEhITQ+0BOZfWRI0dStXUzMzP8+uuvGDlyJABg1KhR+PLLL7VuG78HbW1tUaZMGQDApEmTqOh2tWrVUL16dZXf4QWQJ02apDJ4y0lERAQmTZpU4DG8SK++BkYAKF++PDZu3AhAmnAsXboUgNQXjRkzRi82BQUF0YSsfv36GDZsGBW2btmyJRWIHzVqFMzNzalQvbYRblWBQCAQCNTQ+rq5oNmGsgurQYMGsru0GjRooPHq4MqVKwCAc+fO0WrRz88PtWvXls0+derVq4fu3bsDyNm0B4C3b9+SmzM/uMtTjugyXihVudBofih//7wAtqOjI4YMGSLbCnLr1q1wd3fP87Pr168jMTGRfjYxMdHGBv4HSZcuXQBI2yH8mpUtW5YK4G7atAlfffUVLC0tAQCGhobksh43bhy8vb3x7bffAgDmz5+vjSK0ueAeAmNjY3L38y2RvLh58ybWr18PQNpOqVevntZtUoZ7WfgKOj8qVaqEsWPHymqLpvAgHE9PTxw/fhyAFLzGvVi6ZsiQIbRSVLchODiYrq1CoUCDBg2oCLy20UnvwPcjAwIC6L0aNWqQu0PfnDlzRqVTNzQ0BIBc7hldMHz4cADSDRIZGQkAWLRoUYGDY7169dC8eXMA2uvwK1euDEDqeApKdSmIP/74g/5VKBT46aeftGKbOnXr1sXff/+d52f9+/fH3r176efly5ejRo0astjxX8fJyQmA5O6rW7cuAOkZ4DED6nh7e8Pb2xuA1FFNnjwZc+fOldXGHj16AABatGhR4OSa37P9+vWjzv/MmTOyu/h5W8HBwahatSpiY2NzHdOuXTssWLCAnll9w/duDx8+TIMjH5z0hfqgePjwYQBQyRwYPnw4RQDLgeyDY1RUFL755hsA0g3D93/atm0rd9MacejQIfTr1w8ZGRn03vbt2wFAlplvQSQmJmLmzJkAAB8fH9oH5eHgeTFlyhTMmjWLBnRtMWvWLABSENVvv/0GAFi3bh0AoG/fvgDy3rPjaTyrV69Web+oA2xR4eknVapUoXuuX79+JTaoqCSgyR5TRkYG7VFt2bKF7ldd58QVNDCePXsWo0aNAiAF5vE0ALlXjUDO5NTOzg4LFy4kTxCQszL39PREmzZtZLdFUw4cOAAA+Oabb/Q+KObF2rVrsXbtWgBSbIidnR0AKRCLezXkQOw5CgQCgUCghqwrx7/++gu3b9/G7du3AahGEnL3iD5ITEwkV8KyZctUVo1ATgLqmzdvYGxsjHLlysluE2MMu3fvzrXieh/NmjXT+qpRmQoVKtAsnP+bHxEREThy5Eiu97/99ltZ3R/qpKam0mr36tWrdN89e/YMf/75J+2dtm/fXmc2/Zfh+4rr1q3D0aNHKT1q48aN6NSpkz5NI3gU6+bNm7Fs2TJamS1YsIBWGrqAu6adnJwogpbDV2jFjSbXNu/evQMgRZzz1Ak5V2Sa8OLFCwBSLMW5c+coehWQYjAASfABAKXeaX27hDFW0KtILF68mC1evJgZGhqyUqVKqbwUCgVTKBTsp59+YpcuXWLXr19n169fL2pTheLp06fs6dOnrF69egySWsh7X82aNWNz5sxhc+bMYUFBQbLZFhAQwKpWrUrXR9OXhYUFO3v2LHv+/Dl7/vy5bPblRWJiIjtw4AA7cOAA69WrFzMzMyO7GjduzLZs2cK2bNnCkpKSZLclIyODZWRksEuXLjFnZ+c87zn+s6GhITM0NGRfffUVS05OZsnJyYVt7n3PTUl9aUxsbCyLjY1lJ0+eZObm5szc3JyZmJiwX3/9VeWaxcXF0Ss2NpY9fvyYPX78uDBNFZm3b9+yt2/fst9++41VrVqVVa1alY0ePZpduHBBJ+2/j969e9O9N3fuXJadnc2ys7P1bVYu9u3bx/bt28cMDAyYlZUVs7KyYr1792bnz5/Xiz0nT55krVq1Yq1atco1fuT1PFtYWDALC4vi2Jvn8yLcqgKBQCAQqKF1bVVASvYHcgJblOFL3+joaGRmZsLIyAiAFNHIVRHkgrtylV1/pqamaNasWZ6ai5mZmdi5cycl2CsUCgojXrFihdbt8/T0xC+//FKk323RogUAwN/fX1Y3a3JyMimOrFixgkLXOTyabPPmzaRXqwt40jp3aynDRSg+/vhjDBkyhCIsL1++TN/7oUOHCtPcB62tumfPHnKDR0ZGUvDctGnTSNUFkNIWuHYxID0vPDLd1taW1KW+/vprdO7cGUDBgTSawNM3du3aha1btwKQBAhGjx4NQIqubtu2LfUzFSpUKFZ7xaFPnz44ePAgACmFiAeV1K1bt0QGvmzcuJH6n9DQUBgYGGDEiBEApChvLrogF3yra/jw4SpuVAAU6V6hQgXSkb58+TJOnDihEkA5f/58ACC7NSTP51mWwZFHLH799ddISEggKSd7e3tS1PDx8cG9e/doj83R0ZHyfuTaj/z3338BAN9//z3tQy1atOi9kbP84k+ZMoX2XxYuXPjePbjC4uPjQ9JcQE6eIPf/8+jVX375haqNREVFITw8nDqfFStW4JNPPtGqXcrcuXMH9vb2+X7Ov+vBgwfTgK2LKEb+XXD1DH49pk2bRtfDzMwMAKjDcnFxoc+4CoyGfHCDY1JSEubNmwdA2odX7hdKlcpxMCnn39asWZPyS9XTsvbs2UO5klFRUZTSMH36dMyZM6fIfwDfX1KXpuNVd7iyFLe/Y8eONGHTdYT8tGnT4OXllet9U1NT1KpVi65d79699ZI2VhCrV6/GnDlzaLLTs2dPUjeTIwYjIiICjRs3BiBFRPPI4n79+mHYsGGUW6uugJWdnU2SpJMmTaIIen9/f3z00UeaNq+7wbEw8PSAMWPG0A397NkzuhgliZkzZ1LZqDp16iAiIkJvtnCJu7CwMDg5OdGMfvv27Rg4cKBs7UZGRmLYsGH0c1xcHAAp2V4dXnJLF0Eb/HvZu3cvBg8ejJ49ewIA5espw2fwY8eOpXSdq1ev0gpTAz64wdHGxgZhYWEApHQEnsyvvPp3dnZWeS6trKw0EoYIDQ2liW9AQAC2bt1K55cLrhEaGBhIg7GDgwN+++03naWcJCcnY8KECQAkkZHg4GAAgHqfa2dnR9d1y5YtJUbv99mzZ/Ts3r9/n7wyJ06c0HpbERERJEtoZWVFbRQk8KBOz549ySu4atWqwogsiKocAoFAIBBoRH6ROqwY0aqFwd3dnbm7u6tEIT179kwXTReaGzduUBSrgYEBu3jxIrt48aJebTp79qxK9Oq8efN02n5CQgJLSEhgV65cYcOGDWPNmzdnzZs3ZwqFgqIcFy1apFOb3oePjw/z8fFRuef8/f0Lcwp9R51qPVq1TZs2zMPDg3l4eLCIiIjCXItC4ezszKRuR3fwe7Rt27bM1NSUvX79mr1+/VqnNjDG2J49e9iePXtY7dq1840+t7OzY6tXr6boa33Do+DLly/P7O3tmb29vb5NypeAgACKYLWxsWGvXr1ir1690uRX83xe9CouGRISohIIwffWSloeEEdZ0ig7O1tl/+V9cDeogYFBsSXesrOzyW3E5eb4Zvlnn31WrHMXFhMTEwCSWn7Lli1pj2LQoEGkTLJq1SpERkaSO1Of3++bN2/I1QVI7kRA/3JZ+ubChQuynp8HWOiqKoYy/B49duwYOnXqRNsOXCpNV/Dizw4ODjh16hQ2b94MAAgPDycVrDt37mDcuHEUXzBu3DiVPV9dU9L75PwIDw+nuAxNXP95IdyqAoFAIBCoodeVY2JiokqNQL7SKOpILzc7duyg/1tbW2usj5iVlUV6lMHBwVTkubApFzExMQCAiRMn5kqT4VFa+lZ94QEuO3fupDp1jx8/xubNm7F48WIAOVGj+mD79u20knj79i0VvpU7TP3/mbCwMEyePBmAVKtPX3UCjY2NMX/+fDg7OwOQVheFCMLSGjY2NrCxsaH0k4SEBCxbtgyAFD0PgLwbbdq0oahvfZJXndQPHb0Ojsr5hj169ECTJk30aE3eREVFwd/fH4CU68OpVKmSxufYsWMHxo8fTz9zF96AAQPyjZz7999/SSbpzp07OH78OKUb8LxLToMGDSj/UhdlmHhuW4MGDfKNKq5UqRLWrFkDAFi8eDGuXLlCMoL6GsAfPnyI2bNnq5Sw2r17t15sKYlwGcWbN28Wu0POyspSSYHi97KXl5dWSjW9fv26SFV9WrRoQVXlfX19dSprmB+VKlWi/LxSpUpR5DUgFQDgUd/6gKe/paamypo/rQ327dtH/69WrVqxo5L1NjiGhYVhz549FNbcrl07fZmCrKws2j98+vQpzpw5A0AKQd+5cyet2ADQSqMwnaq6tuPQoUMBSEmv+SXK37x5E69evXrvuZs0aYI9e/bQ3pncvHnzBj///DMA4KOPPiowrJvv0b58+RJAzmRI14Mjr2DP8zO58MTOnTv1uootaRw9ehSAlF6VXwmwgggPD6drvW3bNgQGBgKQUmZ4RQptVb2fMWMG5bQWhlOnTtG+uC6qdGgKX5k5Oztj2bJltAdZUEUeXfD9998DkPrIKVOm6NWW/OATL36/AVLJv+KmA4o9R4FAIBAI1NDaypHPxvr06YPw8HAA0kien/KDi4sLnjx5QrUetVUIlyelT5s2TcV9VhDXr19HaGjoe48bOHAgqYjUrl1bY5tsbGyoWjUvYAwgl/Sapjg4OJDSUI8ePQrl4i0uUVFRpEaSXxFcQFpZT58+HUDO38xt1haXL18GICm6LF26FEDu1cDDhw+phiOfnS9cuBCAfivDlES+/PJLANKz+OeffwLIqd2ZFzExMbhy5QoAqeLEn3/+SZ6Q0aNHk1uV7/Fqk6ioKJIRW7lypUa/8+rVK9rnA1Ciaipyz9Vvv/2m89Ui91Ddu3cPTZs2BSBlEgwZMoSi4j09PdGrVy+d2qUJp06dIjd9WFgYfae8zmhx0NrgyAMxHBwcaE+qW7dumD17NmmmRkZGkgRReHg47OzsSE+P7wMUF67y8dtvv+XS5yssNWrUQKdOnaj0TIcOHYoknVSxYkVcvXoVgBQQwuWOeHkYTeFBIytXrtR74A0gBVfwAc/a2hpbt27Fs2fPAEhlcHg4OiDpNmq7pAwPcjp8+DBJFrq5uSE1NZV0N1NSUqgkj0Khx2CnHwAAIABJREFUQO/evVUUfgQ5VK5cGQAwb948zJ07F4D0nPKtBHWmTp1K33erVq0wY8YMDBkyBABgbm4uq61ubm70PQ4ZMgS2trb5Hsv3zVxcXBAdHU0BQfpSoklISMDz58+pIHd4eDiysrIA5KhK8QkFT9WSE/4d9urVixY5HF6smd8PuiA6Ohrr168HIGn08hQYTlBQEABpcTFr1ixyq3bq1Ins1IYKknCrCgQCgUCghta1VYODg7FlyxYA0sze1NSUVjm3b9/GgwcPAEirqTVr1mDw4MGFbUIjzp07hx07dlAwTdmyZen/MTExaNSoEQAgNjY2lyuuf//+AKTZsByVJfhKZvPmzSrBPkBOOkvDhg1JrLlly5Zo1qwZOnToACBnla4PsrOzyb3CAzjyg8/mp0+fjr59+2o9mZlfOw8PDxITzyvknIfrjxgxAsOGDdOGcPJ/Na5d4+eZR2grR5YmJCQgLS2NVoVffPEFRXtaWFjoJFKak5WVRaIS8+fPJw3QPn36qGzlLFmyhP6WypUrY9myZXBxcQEAlC5dWmf2KrN27VqsWLECT548yfeYvXv3AijYra1tbt++DQ8PDwDSatvLy4uKH+hSBCAiIoLGjLi4OEyaNIm8GpcvX6biDElJSTA1NaW0F09Pz6I+27oXHq9VqxYt2QFpj4cr4uzatYsGIcF/C+4uXbZsGe0rcnilgdmzZ1MnqotOk+eHbdu2TUXo3NbWljoYLUamfvCDY168fv0a6enpJUYYmxMREUFpQwEBAbh16xZ91+3atcMXX3wBQHJR8khlfbNt2zaa3L19+5aifHmaF4/B0OdEWJ/w6zF79mwVFbWJEydSf2JkZISxY8dqoyyZEB4XCAQCgUAT9F6ySiD4D/J/uXIUCD5QxMpRIBAIBAJNEIOjQCAQCARqiMFRIBAIBAI1xOAoEAgEAoEaYnAUCAQCgUANMTgKBAKBQKCGGBwFAoFAIFBDDI4CgUAgEKghu64XY4yKBw8YMIAkk+rXr485c+aQdp8uefjwIclNXb9+HbVq1aLPFi1aVKhyVAKBQCDQPSNGjMCGDRtIzrBjx44qn3OBGzc3NyrHVhjEylEgEAgEAjVkl4/r378/KcyrU65cOar9WFDhXG3g4eGBbdu2AZAqS+RX67Fs2bJUU60os43iwtXoz58/T+/Z2dnhjz/+IAFeZ2dnVKlSBQCoiLIuSE1NxZMnT6jqSkpKCvbt2wcAePnyJSwsLKjIqKurqzaFvjXmq6++wpUrV+g7tLW1peLbZmZmCA8Pp++1GDXfhHycQCNSU1MBAGfOnKEqNps2bUK/fv3g5uYGAHByctKbff9ltmzZAnd3d1ohqlfk4e+XLVsWderUwcmTJwEgr/qkuqvKwQt3Jicno2XLlggNDaXPlKvWJyQk4Pjx4wDkv0Hq169PRTHnzJlD5Z+qVaumclz37t2pMPGBAweoULOu4B238uAISF+08pffuHFjAJK6/6effiqbPS9evMDIkSMBSEVIeeX39+Hg4EAFS1u3bi2bfZzJkycDAFatWoWMjIwCj23WrBkAqVhv7969i9LcBz04vn79mkoUGRsb0/V8/fo1AGkrApDuUeV7UrnShPL9evLkyVwur/8HvLy8cOTIEQDI87nh92FgYKBO7VImMTERCxYsACCVy+PVMACpMkiPHj0AQOf9oCZkZGTg/v37VMxaoVCQi3X//v1UTD4kJAS3b9+mslf8PlZCaKsKBAKBQKAJWl85BgYGwtvbGwAQFRWFe/fuUU1Ha2tr/PrrrwCAoUOH4tmzZzpbOY4fP56W0+PHj8/3uEOHDlEx3xUrVsDT01NWu9QJCgoCILlXk5KS6H31lSOnefPmtNLVJrzQcqdOnXDr1i0AQOfOnamAMYcXjj18+DAiIyPh6+sLQKr5aGhoCAD4/fff0a9fP63bGB8fD0D6zkaMGAFAcvVqSvny5cnVXsiish/kynHJkiUAgKVLl+Ljjz8GADRt2pSuMy/ETSfL557kn/E6e2fOnJF926QkwBjDy5cvAUj309WrV8mLVqZMGarRGB8fjz/++IPqnUZHR+vF3gMHDmDx4sXU5+TF3LlzAYC2S/5L8JVjhw4d8ODBA3o/Oztb/dA8b2KtR6s+efIEe/bsASD5201MTBAQEAAAaNKkCQ4cOAAAKkWQdcGqVas0Ok75RlF2AeuKzz77DIA0gPPOpV69eggICKD92bt379Lx165dk8WOUqUkpwIf4ACo7JOo07JlSwDArFmzAEhuVb7f4u/vL8vgyF1V+dkESG7ycePG0c/r1q3DwYMHAUgDKS+SrMuK6yUVfn/Fx8fTgHj37t18B0AbGxsMHz4cALBz506VZ6dcuXIUEa6tgTEmJob2jwGQO433L5zXr1+TO9PKygrz5s0DAAwcOFArduRHRkYGTSoAactm9OjRAIAZM2bQ+15eXrLaoSlLly4FAAwePBiAZK+xsTGAnOd46NCherGtqNy/fx+AdI354BgaGgpDQ0Ps2LGjUOcSblWBQCAQCNTQ+spx586dtGKoXLkyDh06hDZt2gAATp8+jZUrV9JncXFx2m6+yHC33MaNGynYRZ+rCT7b5bi4uGD27NkAVFeOcsEjTQ8fPkyb9A0bNnzv7/GVZn6rDV3Qrl07WrXUrl0bJiYm9JmFhQWtKjIzM9GoUSO92FgS2bBhAwDg559/xuHDhwFIngy+iuQrtbNnzwKQgsL++ecfAEBYWJjKuTZu3Ijvv/++2DbxlX1KSgp8fHzIBVmqVClyS6pTpUoVTJw4EQDw999/w93dHQDQoEEDtGjRotg25cfy5cvp/5aWljh27Bjs7e1zHXfv3j0AQJ06dWSzRRP2798Pc3NzuqZWVlaFXl3Jxbt37wDk3HOPHj0CAJUc9AYNGqB8+fJ48uQJACkj4eLFi/T7fMuwbdu2mD59Ojp37lw4IxhjBb0KTd++fVmNGjVYjRo1WHR0NGOMsYyMDJaRkcE8PDyYg4MDc3BwYIaGhszJyYk9ePCAPXjwoChNaYXExES2ZMkSBmk/hjVq1IhdvHiRXbx4UW82cZ48ecKePHnCZsyYwWxtbclG5VevXr30bSZjjLG0tDS2Zs0aVrlyZVa5cmWmUCjotXnzZlnaPHHiBDtx4oTK9di2bRt7+/Ztvr9Tv359OtbS0pIlJSWxpKSkwjb9vuempL40Ijk5mb18+ZK9fPmSJSYmsjVr1rA1a9awUqVKMVdXV5aVlcWysrLYsWPHmJGRETMyMmKlSpVibm5ubN++fWzfvn2FvJz5Y21tzaytrdmMGTPo+z5x4gT7+++/NT6HmZkZMzMzYyNHjtSaXcqcOnWKnTp1ipUpU4bu+aNHj+Y6LiYmhsXExDAjIyNWtmxZdvz4cXb8+HFZbCoKR48eZaampszU1JQpFAo2depUlp6eztLT03XSfmZmJsvMzGRubm6sdu3arHbt2ir9iEKhYADo/w4ODmz48OEqfU61atVYtWrV2BdffMGCg4NZcHAwy8jIeF/TeT4vWh8cnz9/zhITE1liYiK9t2jRIrZo0SKmUCiYpaUls7S0ZAqFgsXHxxeliWIzf/581q5dO9auXTtmY2PDALCuXbuyrl27sufPn+vFprzo168f69evX66bQqFQsI8++oh99NFH7OnTpzq368WLF+zFixfsxo0b9GrZsmWuG3n06NFs9OjR7M2bN7LYwSddgYGBLCoqikVFRbHs7Oxcx/HOfPjw4SoD6YABA4ratL4HOVkHx/wIDAxkycnJzNzcnJmbmzMArH79+qx+/frszz//LO7p8yQtLY2lpaWxrKysQv0evze8vLyYoaEhMzQ0lG1wHDduHBs3bhx12A4ODiwqKirXcY6OjszR0ZEpFArm6ekpiy3F4YcfflB5fu/du6fT9uPj41l8fDyztLSkZ7SgwVH5PQDMw8ODvX37tsDJcT7k+byIPUeBQCAQCNTQ+p6jcrQW5+HDh/T/5ORkAMCUKVNQsWJFbTevEcnJyZT+kJWVBWtrayxbtgwAKIm0JGNoaEhRvzVq1NBZu4GBgTh16hR8fHwAgHz9+cEFDXjyrbYxMJBu3+bNmxd4HFdo4ntqPLF5586dstj1oVKlShUMGDCA0nz69++PhQsXAoBsesRcjKAwhIeHUwTzxYsX6RkZNmyYVm3j8AjJMmXK4MSJEwCA6tWrqxzj7e2Ny5cv089NmzaVxZbCkp6eTrEMu3fvpliBBQsWwMbGRqe28O/azMwMz58/ByB5Nq2trckWppQ+9M033+DNmzeYM2cOAGkPnEfbagPZhcfV4Zv7hoaGKF26tK6bByBt8vMAnIiICLRv354CM+bPn49JkyYBKNqDqU14+sPx48eRmJhI76empmLr1q0AgM8//1xn9nh7e+P333+nnw0MDGiCU6FCBXTp0gW7d+8GACQlJWHjxo0ApHQKfX3Xq1atyhU6X+iNeQEAKWjt9OnTJNS/aNEincoX5sfNmzcpyCooKAh+fn6k6lOzZk26D+3s7GRpv1y5cgCAFi1a5BoUefCNp6eninKTu7s7fv75ZwBSjjdP9bCyslJJn5KTuXPn4uTJkyrqPTxg6eeff6Z0Ll3B5RzPnz+vIu9ZoUKFAgc9bnOfPn1gamoKQDtpO8KtKhAIBAKBGrILjwPAjz/+CAC02gEkV9vjx4/15lpVZufOnZgyZQoA4Pnz53B2dgYArFmzBvXq1dOnaQByVHuU0yOMjIwAALdu3ULdunV1YseCBQtw7NgxcmN26dIll7IRF1fu3bs3qYOsXLlSJRFfF3CXb4sWLUi1BAC2b9+OAQMGAEBxZsYfpEJOfrx69QoA4OjoiLCwMAQHBwNALrUkOZk7dy7i4uIoVF85dSQ1NVVlpVG+fHkS5n/27BmtxKZNm4bvvvtO688LFzR5+fLl/9g777Aorq+PfxeVIhZsiIodu0YsGDUWQBB7gpqIiS0au1HxZ40FRcESe0c0iSXWICZGscauYBQLNtSoiCgoWJAucN8/5r3X3aUtMLOLej7Ps4/s7uzMcXdmzr3nnvM9QsRDm9WrVyMkJAQAcP36ddy8eVMjGsSxtbVFp06dROi/RYsWipVFNW3aVKhfadOpUydMmzZNLIkNGjTIoOVZ2fHo0SMAksgMV3kaMWJEbnahP+FxbfhNcu7cuVi1ahUA4NWrV1i4cKGoRzI0/OIaOHCgUPhp0aIFfH19M61VMgT8RPXy8hIqL1u2bEGPHj0MaVamFCtWTKwvjxgxQsgG6gsezuI1q5zNmzeLkAs5x9wxc+ZMeHt7o0uXLgDeD4T0wa1btzQcoHpHmDJlymgIY5uZmYk63a1bt4rlkaVLlyImJga2trYApLwHPhDWNzdu3BCKRAcPHhQdI7SZOXOmkHCTm0ePHmHDhg24cuUKAGndmK/Pa9eg9+rVC3v27FHEjvzCJzaLFi0S/oQ7SR3JWgMxm4fsHDt2jB07doypVCq2YMECJQ6RL1JSUtjUqVPZ1KlTGQDm4uKSoTSlIDBt2jQ2bdo0plKp2L179wxtTgZ27twpUq1NTU3Z4cOH9Xr8pKQklpSUxBwcHDLUho4cOZKNHDkyP7s3dEmGQUo5Hj58yGrVqiV+186dO7Po6GgWHR2d313rhXfv3rGVK1cyBwcH5uDgwFQqFXN1dWWurq4sODjYoHatW7eOrVu3jk2dOpWZmpqK77hw4cLs0KFD7NChQ3qx5datW+zWrVvszJkzbMaMGRp2+Pn5MT8/P73YkRt4TSQA5u/vz/z9/XO7CyrlIAiCIAhd0EtYVR0e7mrYsCFMTExEaMbJyUnuQ+WZ5ORkAICrqysCAgLEWoE+11hygsfZP//8c1SsWFGUphg6w5aTkJAAR0dHAFIJSLVq1YQUlD55/fq1+D3d3d010tVtbW0RHBycl91+kmFVAPj777+F2HhERIQo0/n1119ha2ubWSPZAgdf5rlw4QL69+8PQFov5B1leNjYUOzatUt08FDP+uYyePri9evXqF27NgCpS8/q1asBvJfalAP10rn69esDkCQLedZvhw4dUKRIEfGeNj/99BPmz58PQFoS42VmvMxLR/TTlSMn1NveJCcnIzU1Vd8m5AhPza5Xrx4CAgLw999/A1DGOR45cgSA1NWax/t1gXcMKVq0KK5evSpqqNq3by+7jXmhaNGiot2Xm5ubwezgqd2AdAM/fvy4SDDJpOkpkQPdunUT18GUKVOEQ3F1dUXFihVFh4cOHTrA3t7eQFZmDy8ratOmjUguql27NgYOHAgAomGzoejTp49oQHzz5k1R06xv52hhYYGxY8cCeN+lQ264rqtKpRKJcydOnACftKlUKg3nyJPpACkRSz2XoU+fPrl1itlCYVWCIAiC0EL2mWNKSgrOnz8PQApbpaeno0iRIgCkYl0+IjIEPKR79OhRjBs3Lsft27Zti6VLl2o0HZabTZs2AQD27NmDGTNm6FyozEe8YWFhsLGxQfPmzWW1i2er3bt3L8+dDPz8/OQ0Kc9cv34dgBRW5bNGIu/wwv/ly5eL4vVVq1YhMDBQdNFYtGgRvvrqKwDIVURE3/BuD+np6UL5pyDA1XzGjh2rMVvSN3zZQanlGt6ZhP8OmfHu3Ttxv7t69WqWJSVyK3HJ7hyPHz+Orl27ApCaZ6akpIjQVlhYmMa2pqamoh5JacLDw9GhQwcAyLHmjqv4HDp0CADg7OysmF28ndfu3bvRrl07cUzePDgzwsLCRIiFMYYiRYqIukc5+Ouvv8RNb8uWLXnax99//y1q0gwBb5vm5eUlmuHyf7nCC29rReSNChUqiDWjVatW4d27d6Iu+Pnz5xnaWMkBH9z07dtXDNpsbGxEqNfCwgIvX74U2/OSDkAqPYmJiRFNmUNCQsS1XrFiRcVCh3lBfRB36tQpAMo3a84MvlzTqFEjRWrSv/jiCwBSa6revXsDkMow1O8dSUlJogQwJCQE2nkyHTt2BCC/A1d0zZHH7t+8eZPp+9bW1jnqYsrFr7/+KuLb+/fvF9qGdnZ2KFWqlLigVq5ciQ0bNgAAnj17hu7du2dZ2CsHPCHg4cOHWLZsmSj+HThwoKjBsre3R3BwsKiF2rBhgxhoqFQq9OzZU1ab1LVweU2YLjx79kz0ARw/fryoS6tfv76iN56oqCiMGTMGwPs+cLzAWttBV6lSBXPnzgWAAlkf+iHAIynaA7IxY8aIm7pKpcL06dNlPzbv4bhlyxaRfHHgwAEsWbIEgHTulilTRvy24eHhOHbsmMY++Bp4zZo1Rc/Jpk2bilwDpVi/fj0AKSozbdq0LLcLCgoSWs/Aey1gfbNnzx4xeKhevbos/Tm1+emnnwBIfWP5xMDU1FTMlv/55x8kJiYiPDxcfIafd40aNcK6detydY/KDbTmSBAEQRDaZFUAyfJYNPzkyRM2duxYNnbs2Ax9t7QfFy9ezMsh8kRsbCzr2LEj69ixIzM1NRUF4YULF2YuLi4aReImJibMxMSEjRkzJi+NcPNEQkICc3BwEMdWqVTib0tLS43CYPXH4MGDWUJCgqy2DBw4UDQNdXd3ZyEhISwkJIQ9f/6cPXjwgN2+fZvdvn2bubu7s65du7KuXbsyY2NjjWavKpWKNW/enDVv3pwdPXpUVvu00f79tB8VKlRgFSpUYL1792a3b9+W45CGLuY3iAgAY4zt3buXzZo1i82aNYsxxtilS5fYpUuXmLOzMzMyMhIPR0dHOQ73UeHp6ck8PT2ZkZER8/T0ZGFhYSwsLIxFRUWxBw8esAcPHrDRo0drXEfGxsbs+PHj7Pjx43q3t169eqxq1aqsatWqujQMzhcrV65kJUuWZCVLltTo0ZhZ78aJEyeyiRMnytknNtPrRZE6R15HtHz5cnh5eYmpOfB+ofmrr76Ck5OTQbo1JCYmihRgf39/VKlSBZUqVQIgrQFyuTil2vBkx8mTJwFIa2XHjx8XrzO1Vi3Ae1m0LVu2yN7+5o8//hAdQYD3NUMVKlTQCG9oY2FhIdZKhw8fjpYtWwLI2L5HbmxtbcWCvTZWVlaillbGpKVPss7Rz88PQ4YMEet4tWrVws2bNwFIIfWKFSuKVlGenp75NPXjg8u08WUaHsYtU6YMnj59qrFt5cqVAUgJe/qsAedJSRs3boSnp6fQKF26dKnix+a12z4+PkIa8OHDh2jQoIH4zr777jtRribjGmOm1zOFVQmCIAhCC70r5BC6kZqaKhbtlyxZAgsLC7FI3bx5czF6UqKfHmNMJOX8999/olceTyjgdOzYUTQhHTp0KEqWLClGvPokMDBQ9GiMjY1Fjx49RN/JwoULy9oA9f/5JGeOEyZMwIoVK97vTC2a4eTkhPnz56Np06b5s/AjhkfUPD09RVKYNl988QW6d+8uxBR4ApI+OHnypEiKWbRoEWrXri1ESj4E5aN8YLiuHATxkfFJOse7d+/if//7n8hCb9++vciobt26dYGRLiR05+zZszh69CgAKYRbtGhRAEDLli0xb968j90pciisShAEQRC6QDNHgsg9n+TMkSA+UmjmSBAEQRC6QM6RIAiCILQg50gQBEEQWpBzJAiCIAgtyDkSBEEQhBbkHAmCIAhCC3KOBEEQBKEFOccCyq1bt1C3bl3UrVsXKpVK4/Htt9/i+fPn1NVejZCQEISEhGDs2LEwMzMT31WfPn3QokULtGjRAhUrVsTYsWNx48YN3LhxQ/R+JPLP27dvhXB0dkRFRSlvDKSO8VevXsXgwYPRpk0btGnTBv3798fMmTP1cnziw0dREYBt27ZpyE2pazF+/fXX6NSpk5CfAoCSJUsCAMzMzPJz2A8ars7foEGDLJtEA++bEB84cEB0Y/9USUpKQq1atQAAEREROn+uW7dumDdvHgCITiw6QiIAkK5n3kXGzc0NXbp0wa+//irej42NBSA1rOX6vH5+ftme13Kwbt06uLu7AwCSk5OF3u/r16/x9u1b0XFm165dsh+bd6y/cOEC0tPTNY7Bu8LMmTMHXbp0kf3YuvDu3TusXLkSgNSMfunSpXj37l2W23ON4gEDBmh0BdIXr169QpcuXRAUFARA8huLFi0CAFStWlWuw5AIAEEQBEHogqIzR29vb40whnZPQo0DMYavvvoKALB582YlOilocPbsWQDv+5dlRr169UTXCX1x9epVAFJfyYSEBABAw4YNMXPmTNjZ2QEAPDw8sHXrVgDArFmzMHv2bFltCAkJwc8//wxAmv1nBz9/VCoVmjRpgt69ewMABg0apLcZbUpKClq0aAEAuH79OoD3PSjT0tJgZCSNAY2MjDKMkvl5FhMTIz6jA5/0zPHGjRsAgP379+Onn34CAPTt2xf/+9//cOvWLQDA6dOnxawjNTVVfLZEiRKKzhwnTZqEdevWid917dq1ooNNcHAwRo8eLc7Za9euyRqlGj58uBDxHjp0qOh7yTlx4gQAafbs6+srOm/ok59//hm+vr6Zvte1a1eEhoYCkO5DkZGR4r3k5GQUKVJELzZmBu+F6e7ujkuXLgEANmzYgG+//VaO3eu/K0dMTAzc3d1FW6UbN26Im+edO3fw119/ISQkRDqQmuMcOnRohvZIuhAcHCzCGjlx+PBhAFKT1qxo0qQJnJ2dsXDhwlzbkl+2bNmCpKQkAFJjaPXWNfv37xffY5s2bTSaIsvBqFGj4OPjo9O26s5RnS5duogmw/qAD3L27t0LAHBwcAAgnXM8/FKxYkV07tw508bIubz4P0nnGBsbi2XLlmHTpk0AgPDwcOGEWrdujRMnTojm5e3bt4erqysAyUHxQcv06dOzbNeUH44dOwYA6NWrF0aMGIFJkyYBAMqWLSu2SU9Ph4uLi9j2999/l+Xmyu9hv//+uxgslChRIsN2fEDetm1bXLx4UQx2CxJ3794FAMycORN79uxB+fLlAUi/dS4Gj4qRlpaG1atXAwAOHjwo7uP5hMKqBEEQBKELig4FypQpgy1btmT5fmpqqhh1qRMWFpan47Vp0waJiYl5+mxmXLlyBdeuXRN96pQY8WbFgAEDMrzGZ0fjxo3LdhE9r4wbNw6A1Ndt+vTpAIARI0Zk+xk+iuOza97/jSe66As+Qxg2bJjG6zxRB5C+P6XD9R8jfNY3YsQIXLhwQeM9HjKNjY3Fhg0bRKJJuXLlxLlz7do1EaafOHGiIjby6MDevXvRoUOHTLdZsmQJjh07hkqVKgGAbDO3Ro0aAQAWLFiQ7XY3b94EAJQvX75A9UlMTk4GAEyePBk7duwAIF0rlSpVwt9//w0ABWLWCACFChUSYfLt27creiyD/Y8fPXqUwXHy0OH8+fPztE83NzeNbDk5SE9PF+FNfcNP2tTUVCxbtkyEjHn2L/A+A04OmjVrBkAK/zRu3BgAcmxg++TJE/F3lSpVsG/fPgAQny8I8At8yJAhGt9doUKFsHTpUgAF5+IvKAQEBAAAli5dKsKBSUlJKFasGNq2bQtAcpb8RsUzzXl5jLOzs3Cku3fvFssASsEHQeqDIY63tzcAKaRbqVIlcd/JbFulOHHiBLy8vABI9zcerjQ0N27cQExMDAAp07ZcuXIApFyGIUOGiEzfggRfFlE6p4HCqgRBEAShhV6Hy5GRkXBycgIAkdXG+eabbzBr1iwAQP369fO0/1WrVmHGjBkAgO+++w7x8fEa7/PssV9++UXj9fDwcJFJNmfOHI33TExMDDLKi4+PF7WM//33X5bb8YxWOcgslJsZ/Hvt0KEDLl68CEBKyNm9e3eBmDGGhISIcN+ePXvE7DAlJUVju969e+PHH3/Uu30FneDgYFELGBcXJxLqRo0ahQEDBmR5PURERKBPnz4AgHPnzonaxu7duytvtBb3798HICX38Zlv1apVsWHDBjg6OurFBsaYSP4ZOHAgnJ2dAQDff/+9Xo6vCx07dhT3ECcnJ5H53rpunfSpAAAgAElEQVR1awNalT38/t2yZUtlD8QYy+4hC1FRUSwqKoqtWrWKGRkZiUfdunWZj48P8/HxketQeaJPnz4MUiZfhse0adMMYtPLly+ZSqXK8WFhYcEOHz6sN7v+++8/Nm3aNDZt2jRmZGTEKlWqxCpVqsQCAgJYUlKS3uzIinXr1jFjY+Nsv7ORI0eykSNHsujo6LweJqfrpqA+dGLLli1s6NChbOjQoez06dMsJSWFpaSk5PiZzz77TOPasbCwYBYWFuzhw4e6HjrPvHnzhr1584a9evWK+fj4sOLFi7PixYszS0tL1rt3b9a7d292+/Ztxe3gJCYmsmHDhml8H7a2tszW1pa5urqyDRs2sN27d7Pdu3ezoKAgvdmljq+vL1OpVOK7CgoKYmlpaSwtLc0g9ujCmTNnmJWVFbOysmLx8fFy7TbT60WRUg6+7rBz5074+fmJBJvQ0FChRNKqVSssWrTI4AkShw8fRt++ffHq1SvxGl9nc3d3h4eHh0EUe16/fg0rKysA0oynVKlSYs2iV69eIoX5hx9+gJGRkVAjUXrtbNCgQaLGEgCmTJkC4P26jqFp27Ytzp07l+02xYoVAyAlIE2bNg0AULRo0dwc5pMs5dDm+fPnItrzyy+/4N27d2jYsCEAwNHREWvXrgUglTjwmWheiY+Px6ZNm0QShomJCYYOHQpASgrj62apqakaMnY7d+4UM9dc/sb5IjExEYsXLxaJQu3btxcRjHv37uHBgweiprBw4cLiOpozZ44oh9EHVlZWGjKU48ePBwBha0GBz27t7e1hb28PAEIpRwaolIMgCIIgdEGRaQafvfz7779CMQIAzM3NRby4adOmShxaZ/ia1K5duzRmje3btxfp6JMnTzaIbQBgYWEh1iv279+Pfv36iZRxAOjXrx8AaZY+evRooWZhbW2tVzsPHDgA4L0mLGfkyJFizdTExERv9vTp0wcXL14U68uZCV3HxcUBALy8vMTa9x9//GEQ7cgPET5inzZtmhBOGDJkCMaOHSsUpd68eSOUWPJzTnKtXEdHRyQkJIjSofPnz2PFihUAIBRTAKB69eoan3dzc0Pt2rUBAK6urjmWW8iFmZlZBpFzbi8gzSx5Fnx6erpY+7ayssLSpUvRv39/vdjp4eEhZv8xMTGilKNUqVIYMmQIKlasqBc7cmLq1KkApO/Vw8NDL8dUVCHn7t27+N///oeDBw9KO2NMpE8fPnxYLPQbAl4PqR1qWbFihThRC/LNkt8k1qxZg9DQUCxZsgQAhOCyUhw/fhyLFy8GAAQGBgopsMy+qy+//BKAJJKufiNVmitXrmTqHJ89e4bBgwdrDIY4169fFyFBHSi4J0b25DusyhhDzZo1AUilHZs3bwYAkWyiDi/vOHToEFq1apWn4/F7R9euXdG+fXuN61Vd3Yafa9rLNP/++68o3eDXDFfP8fLyMqgkWmZMmjQJ69evF0lE+khw40l1EydOFLWYr169QuXKlcUAp169egYr6xg/frwYWEyePBkNGjQAIP3m/BzLJxRWJQiCIAhdUHTmyHFzcwMghTD5DMPe3h6HDx822MiNp/Xb29tnUP3YuXMnAIi09IIInxG1adMGDg4OYmSl7+QhHqbivysPU2oLln/33XfZqiXpi7dv34pZBm+3BAB16tTB7du3dd3NRzVzTE5ORnx8fAah7MyIiYkRYhSTJ0/OMsnlxo0bQoHm6tWreRbw50pQb9++RcmSJfOUrJKWlgZAmiH5+PiI2W6tWrVEuUndunXzZJ8S/Pjjjzhy5AgAScBdn6Vk/BqYMWMG/P39xes2NjZYs2YNgMyjBErSqlUrES5/+vSpaM5gYmKCP//8U46Sjqy7YWTzkIWbN2+ymzdvsvLly2uUcixYsECuQ+SZR48esVatWmmkXJcuXZqVLl2a9enThz1+/NjQJmaKp6cn8/T0ZCqVitnY2LDU1FSWmppqaLM0ULdRpVKxVatWsVWrVhnaLDZ16lQ2depUjfKO6tWr52YXhi7JkLWUw8PDgzVs2FCWcyg9PZ2lp6czNzc3VrlyZVa5cuV87U9uYmNjmbe3N/P29maFCxdmPXr0YD169GCJiYmGNk0QGxvLrK2tmbW1Ndu5c6fBbNi9ezczMzNjZmZmTKVSMWNjY2ZsbMzs7e3ZkydPDGIXY4y9evWKvXr1inXv3p19//33cuwy0+tFL86RExgYqOEcra2t2cuXL9nLly/lPlSu8PLyYs2bN2fNmzfPUOdobGzM3NzcmJubGzt+/LhB7eT4+/szU1NTZmpqylQqFatbt26BdI4REREsIiKCNWrUiBkZGbE1a9awNWvWGNoscUMk5yjRqVMnBoDNnz+fzZ8/PzffgwZPnz5lffv2ZX379mUA2Pbt29n27dvzvD+lmTNnjrjO58yZY2hzNHB2dmbOzs7s66+/Nqgdz58/Z8+fP2fjxo3TuF70WVudFXv37mXOzs5y7CrT64XWHAmCIAhCm6y8JlNg5vjs2TONmWOtWrWEsoWhCQsLY2FhYaxdu3ZZquWYmpqyzZs3s82bN+frWA0bNmQNGzZkCxcuZElJSTory4SEhLCQkBBmZWWlMYqbOHFivuxRivXr17P169cLJZ24uDgWFxdnMHuSkpLY4MGDM1XNyeWM1tAzQFlnjk2bNmUAWMuWLVnLli3zdD2GhoYya2tr8X26uLjopKxjSAIDA8W13aNHD0Obo8GsWbPYrFmzmLW1taFNYYxJ4XKuLKVSqdjMmTMNbRLbu3cvs7GxkWNXmV4vBm1FYGFhoVc1iOzgLWT++usvocawdetWeHh4iHqkpKQk0YYnNjYWY8aMydOxeJ3d1KlTRZ2gv79/tgkRN27cEPWX6uUJjRo1ylBPVRDYtGmTSJkvUaIEli9fDnNz83zvl6ufTJgwATY2NgCkVmLZ1VLyzvVjxozB6dOnNd7j7Yu0W119SvBuOIGBgQAkFSSetJKdglVMTIxQbdq2bRtevHgh2rpxjeOCCC8PmTBhgjgnO3furMix+LVqaWmZq9KwXbt2AQBatGihiF25JTo6WkN5Sp9qQ9nx4MEDxfZNYVWCIAiC0CarKSXTIawaGhrKQkND2Y4dO7LcZsmSJcze3p7Z29szABqhrAEDBuR7Pqw03t7eWYZZ88qOHTvYjh07NL6L7777TkMYOSkpia1bt46tW7eOubu7M0tLS43tnZycmJOTk15EnXXl6dOnbMWKFWzFihWsRIkSInz+5ZdfynaMpk2bsqZNm2p8F4cOHcqw3bFjx9ixY8fEd6f9/alUKmZtbS1C1bnE0OFRWcOq27dvz3BuN27cmDVu3Jj5+fmxH374gf3www9sw4YNbMqUKaxbt26sW7durEqVKmL7atWqsZUrVyoWSr106RJbuHBhvvbx7NkzNn/+fGZiYsJMTExY8eLF2aRJk9ikSZNksjIjXFw8MjJS58+MHDlSiIFfu3ZNMdtyIiYmRiTVNW7cWFw31apVY+fPnzeYXZxVq1YxW1tbOXaV6fWSZ+cYFhYmMqpsbGzYvXv32L179xhjjCUkJLCEhAT2559/stKlS4ubpEqlEn+XLFmS7du3T47/mOwkJiayxMREdu/ePebo6JipY7Syssrz/vkNpHLlyho368KFC4t06cw6S/AM1W7durGLFy+yixcvyvi/zh+RkZGsVatWGmvKLi4uzMXFhT1//ly24/Cbdnbfm7GxscY5p/3o3r076969OwsNDc2rGYZ2crI6x8TERDZt2rQsB4HZPSZPnswmT56seMeLwMBA1rNnz1x/LigoiLm6ujJXV1dmaWnJALD27duz9u3bs2PHjilgqSbcOepawnTy5ElWo0YNFhQUZJBuHdeuXWPXrl1jPj4+7LPPPmPVq1dn1atXZyqVipUvX56VL1+ePX36VO92ZYatrS0bOHCgHLvK9HqhsCpBEARBaJFnhZwHDx4IZYKYmBh8/fXXACQlhX/++QcAEBQUpLkzxsSitI+PD3744Yd8mC4vPNHjjz/+wJMnTwBoCgVzuP7mjh07cqPFmSlv374VLWK2b9+O5OTkLLf97LPPRAsgQzci5Yojd+/exalTpwBIv+f169dRokQJAJKAO9dlLFeunGzH5k1sO3TogPDw8Fx91sLCAoMGDcLo0aMBQGiE5oGPSiEHkK7NO3fuAJDaJmlfuwBgamoKBwcHobE5YsQIlCpVSiFTNXn06BHs7e3FPWP8+PHieilevDjOnz8PQBIh/+OPP8Dva1euXBEt6GxtbdGrVy/F9YfV2b9/PwDp+uBqPEZG0pwkPT0dAHD27FlxHwgLC0NgYKDQoFaa27dvCz3VgwcPClUcrpnMcXNzE221DN3QnLfnq1q1KpYuXSpH8+hMr+d8ycedOHECgNRR/fXr19IH1BwgIN2A+M28Xbt2QlKqWrVqBu/lyImLi0Pbtm0BQEgTZUaFChWE5BhX+peLBw8e4PDhw+IG5evri3bt2gGQMv/q16+vk7yX0jx69Ag//fQTACmjjp8/KpUKFSpUwPLlywFI54SSREVF4cqVKwCAefPmiZujNnXq1BFycaNHj5ZLPPmjc44fAsHBwSJb/OnTp6Jjh52dHaKjo8V21atXF90kmjdvjq5duwKAyG42BHPnztVotJCQkCCkFletWiUy0X18fEQGtZxcu3YNQMbr8uXLlxpC/Fyq7ssvv8TgwYNRpkwZAECNGjUKTCMG3vjA09MTkZGRcmTOyu8cOWfOnBEn4MiRI8XrYWFhGD9+vBzad4ri5uYmUqe1cXV1hYWFBQCp9EJup/ihod3smI/KHRwcsGfPHlnKNT4ACsZdIvd80M7xQ+b58+eihOTYsWM4cOCAKB+bP3++cI5KwaMskyZNwu7duwEAzZo1g4uLC7744guxXZs2bQBkX8JjaFxcXAAAo0aNEgPffEJdOQiCIAhCF/TSlaOgc+nSpQzNejkODg4FehSlbwYNGiRGnh4eHiIq0L59e0OapW9o5kgQHw/KhVUJ4hODnCNBfDxQWJUgCIIgdIGcI0EQBEFokZPw+IcaPiIIIiN0PROEjtDMkSAIgiC0IOdIEARBEFqQcyQIgiAILcg5EgRBEIQW5BwJgiAIQgtyjgRBEAShBTlHgiAIgtCCnCNBEARBaEHOkSAIgiC0IOdIEARBEFqQcyQIgiAILcg5EgRBEIQW5BwJgiAIQgtyjgRBEAShBTlHgiAIgtCCnCNBEARBaEHOkSAIgiC0IOdIEARBEFqQcyQIgiAILcg5EgRBEIQW5BwJgiAIQgtyjgRBEAShBTlHgiAIgtCCnCNBEARBaEHOkSAIgiC0IOdIEARBEFqQcyQIgiAILcg5EgRBEIQW5BwJgiAIQgtyjgRBEAShBTlHgiAIgtCCnCNBEARBaEHOkSAIgiC0IOdIEARBEFqQcyQIgiAILcg5EgRBEIQW5BwJgiAIQgtyjgRBEAShReEc3md6sYIgPixUhjYgj9D1TBAZyfR6ppkjQRAEQWhBzpEgCIIgtCDnSBAEQRBakHMkCIIgCC3IORIEQRCEFjllqxIEQXwwhIWFoUWLFtizZw8AIDo6GtOnTwcALFu2DAAwcOBAAEDp0qURGhoKAKhTpw5UKilp8datW7LZM2LECADA6dOn8dNPPwEAevbsiaJFi8p2DEIZ9OocZ82ahblz5wIAatSoAcYYHj58mGE7xpTPOG/ZsiUA4Pnz5/jiiy/E640aNYKxsTEAwM/PD8nJyTh37hwAoEiRIorbxf/vO3fuxOzZswEA8fHxsLGxwYMHDwAATk5OqFSpEgBg/fr1qFKlCv755x8AQMmSJRWzLTk5GStWrBDPvb298ebNG41tvvzySwDAxIkT0aZNG8VsyY7Zs2djzpw5APRzLn1KTJ06FXFxcRle/++//3D48GGN1/h3z50OZ/To0Vi1apWsds2bNw8AsH37dkRHRwsHGB0djfj4eADAoEGD8Pz5c2HPixcvxN8qlQq9e/eW1SZ1QkNDMWDAAADAggUL0LFjR7i6ugIA/P39cfv2bQDAF198gbt376J27doAgBkzZihmE5E9qhxuHrLcWX799VcAwLBhw5CWlvZ+54zB3NwcAFCrVi0MHToUADBq1Cg5DpstrVq1AgAEBQXBxsZGXPCRkZFimzp16qBevXrYvn07AMDU1FRRm169eoUpU6YAAHx9fbPdln9vjRo1wsGDB1GqVClFbDp48CAWL14MAAgJCUFMTIxOnytatKj43HfffYfixYsrYl9mqN+M7e3tceLECfF89uzZsLe3F+/l9RB5Ns6w5Ot6PnnyJDp37oyUlJT3O8zCAWb1nqWlJby8vDB48OD8mKLB5cuXYWdnJ46pUqk0jq3+d9GiRdGzZ08A0Bi8tW3bFvXq1ZPNJg7fZ2hoKMaPHw8AGDp0KHr27ClmrYwxsR2/rrds2aLxeSUJDw8HADg6OsLExASANHCoX78+Tp48mePnixQpgr179wIAunXrppidCkJ1jgRBEAShC3qZOaqHLooVKwZAGiG1adMGM2fOBAB89tlnchxKZ9RnjlevXkWFChUAQCNMWKFCBTGS0wfh4eGwtbUFAKSnp+P169fivSJFioj3WrRogWHDhgFQ/nsbOXIkfHx8NF6rXr06AKBhw4YYN24cAKBixYrYsWMHrl69Krb7/PPPAUghVh6qVpqTJ0/CwcFB5+357FF9dqkDn+TMkYfVk5KS3u9Qx5kjn9m1atUKFhYW+TEjAwkJCWjRogUAab1QfbZYv359Eb50dXVF0aJFUbduXVmPnxW3b99GgwYNAEjfQVRUFACgbNmySEhIwJ07d8S23CZ9r0VGRESgU6dOAICbN2/meT88MnT58mXY2NjIYlte4JHJhIQE8dqff/6JwMBAPHr0CIB0/5w1a5b6xzK9nvXuHAMCAgAALi4ucuw6T4SHh6Nhw4YApJv6v//+i99//x2AtM749u1bANIaxaBBg0SoQZ/cuHEDjRo1Es8XLFggQq76JDY2Vqwjnjp1CgDE+kidOnX0bk9OZHaT1oUTJ07kJsz6yTjHiIgIBAUFAQAuXbqE2bNn622gkxu487106RIsLS1FOFAfYcnMiI+Ph52dnbhWLC0thXMsKKSmpmLy5MlYvnx5pu9XqVJF497HJw7aeQ3p6eliWerEiRN6G3ykpaVhz5494n4dEBCAp0+fAoA4ZzPD0dERx48fV3+JwqoEQRAEoQuKZ6uePXtW/N2pUyeDzhg569atE6MNOzs7dO7cWWSkqhMUFIRLly7lmByjBPv379d43qxZM73bAAAlSpQQiQR85liiRAmD2KILHh4eIlM1M+zt7dG+fXuN5+r/Epr8+eefGDNmDABpVu7u7o5y5coZ2CpN9u7dK0KUlpaWWLJkicFmjJw7d+4gNDRURDJ4GUdBYsaMGRqzxnLlymHNmjUAgFKlSsHOzk7jWn/y5AkAwNraWmM/aWlpeP78OQCI5Sk5iY+Px4ULFwAANWvWFGU6/v7+CAwM1Ni2dOnSAICOHTuiZs2aAICmTZuKpSAAImqYI4yx7B75IiUlhf3www8MUjiHbdq0Kb+7lIVatWoJm/ijQYMGrEGDBuzcuXNiu02bNjEAzMfHh/n4+OjVxj59+mjYd/ToUb0eX5379++z+/fvM5VKxVQqFRs5ciQbOXIkS0hIMJhN2aH+vXl4eIjXT5w4IdshPtCHzjx+/Jg9fvyYffXVV+K7VKlUzNfXNze70QvDhw8X52bz5s0NbQ5jjDFXV1dhT/PmzdmLFy8MbRJjjLGIiAg2ZcoUNmXKFGZkZMRUKhUzMzNjZmZm7NKlSyw9PZ2lp6ezuLg4FhcXx6KiolhUVBR78eIFS0tLY2lpaXq1NykpifXs2ZMZGRkxIyMjZmxszExNTZmpqSkDwEaPHs1OnjwpHklJSSwpKSm3h8n0eqGwKkEQBEFooWhCzj///AMnJyeRORYZGYny5cvnZ5f5gmdd/vjjj0hNTQUghRL69esHDw8PABlDhpaWlrCysgIAXLx4UfFaR46bmxt27dolnvv6+sLS0hIARN0lIGX/8YxRpXj16hUAoHPnzrh48aJ4vWHDhvjqq6/E8+LFi2PSpEmK2qIL6kk5/HdVh+ocsycpKQmOjo4ApKUFfv2qVCq0atVKY6mkIDBixAix9FG0aFFMmzYN6enpAKSwcNu2bQFIoc2yZcsqagtPwGnQoAFUKpVIDOI2cE6fPi1CwTzzXEkiIiIAADY2NkhOTtZ4j4ubdO7cWXxvvPaRC48YGxuLpKcvv/wSDg4OQqhASWJiYtCiRQt8//33AIAePXqIJKGYmBjY2trKkeGb+fWc1ZSSyRBW7dy5M1OpVKxSpUqsUqVK7PXr1xrvR0REsJs3b7KbN2/m91A6cfv2bXb79m02e/ZsNn/+fDZ//nwWGRmZ7WcWLlwoQjbBwcF6sZOxjGHVrB7W1tbs6dOnerFp69at4rvI6mFiYiIeCxcuZAsXLszwuyuJh4dHjt+Zvb09s7e3z89hDB0eVTSsumDBAhHG4qE3lUrFjIyMmJ+fXy6/KuVRD6vi/8O/UAsF87979uzJbt26pZgdcXFxbPr06Wz69Oni2O3atROPcuXKsXLlyrF27dqJ97l9PXv2VMy+K1euiGPndP3q+rCysmI7duxgO3bskN1exhhLTExkiYmJ7Mcff2TFihVjDx8+ZA8fPlTkWCyL60WRhJzHjx8DAAIDA8EYE6ORffv2YfXq1QCklGsAQtklICBA1MUpBU8xzmw2kRXq5RR//fUXmjRpIrtdusJrptLS0sSo88mTJ1iwYAEWLVoEAIqWnXz77bdISUkRUnWZcfnyZQCSIsjUqVPF35s2bVLMrtzCR/MODg65rW/8JOBJDZkxe/ZsEdFwc3MT9YVcztBQqEcLsvp73759OHLkiFCf4fWPcnHnzh3Mnz9fHFelUuHMmTPiOZ891qtXD/Xr1xefO3XqFPbt2wcAOHLkCKZNmyZrAs+GDRsQHR2t07b8+7KxsUHFihU13uNSn48fP0ZUVBTc3d0BSCVdct4X09PTsXHjRgDAqlWrYGFhIerj9QmtORIEQRCEFoqsOV67dg0AxGiCH0N9FFeqVCm8fPlSvDZp0iQsXLgwL4dTlICAAHTt2hWANOPMzawzP2ivOXbv3h2bN28GII1QO3bsCACi+DYsLAyAVLhrSPjaxs6dOzFt2jQA0rroX3/9pagoujrqwuPapRsANEo9cjj/s+KjXnNMTU0VwuDe3t5CTzczgQVeMjFq1Ch8//33MDMzk8vWXMG1PaOjo1GvXj2x9levXj0xY5swYQKWLVsmbJaz+wYg6ZH6+/trvMbXOLmea1aoixioVCoRbZODMWPGYO3ateJ54cJSwNDc3BwDBw4Uyluff/65+I3Lly+fQa+Zl2tcvnwZnp6eotB+/PjxWLp0ab7t5P/ntWvX4scffxSvFy9eXCipDRgwQIm8Ff2tOUZERLCIiAix5li3bl1Wt25d5ujoyJYuXcqWLl3K1q5dqxF3nzx5cn5ixopx8OBBsWYxe/ZsxY/HU+jLlSsnjtu9e3f28uVLje1sbW2Zra0tA8A6deokYvQFiRIlSrASJUowlUrFhg4damhzBHzNEXlffzT02qHipRzqnDp1ip06dYp17NiRlS9fXmPtCWpre59//jk7duwYO3bsWF4PpSinT58Wa6dGRkaGNkeD/v37s/79+wv75CQ6Oppt2rRJPPj9OT/8+OOP4hwoVqyYLHbyUpEePXpkmS9QunRpNmDAADZgwAB29epVue55VMpBEARBELqgSEIOX8j19/fH6dOnhSKBunoCT839EMirXmdeSExMBCCl0//www8AgJ9//jlbsebLly8LkXJedlIQ4OHonTt34t69ewa25j08zHry5EmRnDN79mzRP5PQpF27duLfR48eiRC+l5cXjh07BkC6Rv799198/fXXAIA9e/agQ4cOhjE4C+rWrZvXMLri8PZZW7dulX3fZcqUkbVFWFhYmCJ2GhlJc7VffvkFGzZsACCVzyUmJuLFixcApOQ+nlC1ZcsWLF26VCQGyY2i8nEmJiZwdnbWeI3X2Fy/fh3AezX34cOHy378tLQ0kVlpY2OjISFUUOFrhkFBQTpLYL148UKjx15B4cCBA4Y2gZCZatWqoVq1agCk7ga8Hs7Lywvbt28X4tT79u0rcM7R399fZJEWVAqyff/99x8AwNnZWaN70eTJk/O975iYGDHAr1mzpshX0Obp06cip2Xw4MHw9PQUtdZy398V11bVhuviXblyBQBE6nONGjVkP9aZM2fQo0cPAO9nZLlFvWBWH905uMiAelPo7KhatSqGDRumiKZhfjhz5oyGw+ZF5XLCbyK57KhByISZmZkoBN+8eTOuX78uBr0FCV5eNHPmTDDG9NY1IjfwxB0+sz19+jSA97N2QxMWFiZaW/HWT82bNwcgtaTLL+7u7iKp6pdffsE333yT6XYVK1YUkUlLS0tcv35dCLrIDa05EgRBEIQWss8cL1y4IEKD2oXB7969w4IFC8RzR0dHxaSTIiIi4OrqKlTm88qSJUtEFwJ9rJP++eefAIC3b9/qpB7fqlWrAqX4zzt3dOrUScy6v/rqK0Vs5LNFBwcHUWKjy7oht5GQF/UmyHKhXpKxd+/eHEsiOHyNyt/fX5QBREdHw9LSUpElnPxw+/ZtDBw4EMD7sKq6SIAh4SIZ3bt312ggXLJkSSGiIEf5Tps2bUSv399++w1OTk4AMhekuHHjBgApxKqkQIDszvHPP/8UzuR///ufxnu3bt3SqC2aM2eOqLmRm2PHjqFw4cL5Wojetm0bzp49i5YtWwKAXnRh/fz8AEj1Tubm5gAyKnkcP35cfI/5df5ykpiYiJ9//hmAFI7mLWO8vLxQqFAh2Y/HL1wHBwdRu3jq1KlsVW8cHJhKxlgAACAASURBVBxEEg7xnvv37+epgztXgPH29kZoaKjcZglnqFKpwBhD1apVAUjnFFeVYYyJEDv/m4cntf/u2LGj4lrEwHvnnFV7r7CwMKFa069fP8THxwOQtGG3bt2quAZsTly9ehXLli3Dtm3bAGjWA1tZWSEgIACNGzeW7XjDhg0Tqmm+vr4iGXHUqFEa28XHx2P06NEApMHOhAkThOa03FBYlSAIgiC0yaoAkuWxaBgAW7x4MVu8eLF4LTo6mkVHR7NSpUqJYs7169fnZfc6061bNzZz5sw8ffby5cvs8uXLrE6dOszCwoKdOXOGnTlzRmYLM2f58uVs+fLlDAArUqQIK1KkCFuwYAFjjImeZRYWFqx69eqsevXqehMdz4mAgADWpEkTjQJxfYnKnzhxQqOwH//fx1G9lyMHkEWE3NDF/LKLADRu3Ficezn1wzt//jw7f/488/Dw0BAlNzIyYlZWVszKyooFBQXl9B3qRL169Vi9evWEALq6GHp2f6vbxf/u3bu3LDZlx61bt9itW7dYtWrVWLVq1VinTp1Yp06d2OnTpzW2a9euXab2e3l5KW6jNrz4/vnz52zYsGFs2LBhzNzcPIPYOL/nXL16VRE7EhISWEJCAnN2ds62cUCNGjVYjRo12IYNG1hqaqoch870epFNPo7XOzk7O4swoIeHB44fP4558+YBAF6/fi3SbpctWyZCJErQrFkz7N69W4T2siMyMhJv374FAPz+++9CxNvY2BirV69Gv379FLNTGx6Oadu2rQhTFS5cGA0bNsS7d+8AADdv3sS5c+cAAK1bt1bUntOnT4tQqampqYb0GgCsWLECgJS6/+LFC9ElfO3atSK7TanQeWbkNmyaw/mfFQUz1z5nsvzP/vbbbxgyZAgAqdO7+nIE/45UKhV+/fVXREVFAQBSUlI03qtcubJYFmjWrJksBquvHf7+++8ijMvUQqlFixYVf8fFxcHS0lJDRnHo0KEANKXklObFixfo0qWLCBWqVCphh0qlgo+Pj7C5SpUqom5QH/YFBwcDAF6+fImAgABRovHXX39l2Jav5/Xr109c67zFlVK8e/dONFbgmcYcc3NzUYEgY/VAptczhVUJgiAIQgvZhcf79OkjahnFTv7/GHXr1hVF+UrX5TVr1gw1atQQdUKMMbx8+RIAcPjwYdSpUwcAEBsbi7Nnz4pMuzJlyogam2HDhuk081QCbeFxdebMmYPp06cDgCKJLup06dIFhw4dynG7IkWKYNSoUSL7WFcBAyVQFx7PDJ7lmo92VR/dzDE2NhZHjhwBIM20YmNj339IbXaoTa1atQBIqkMrV65UtBb48uXLopWROlyEH5DqfsuWLWtwAX5AShjhM599+/YJ4e7Q0FC0bdtW1Fu6uLgoXnvJ78nTp0/H06dPAUAj+1QbExMTNGzYUFxHXbp0UdQ+A5Pp9Sy7c4yJidHoxeXk5IRWrVoBkEohjI2Nc7vLPBEfH48ZM2aIk7Nq1apZKk+0atVK/PhKhnpzw7Nnz0Th/J07d1C1alVRrjBw4EAhtaQ0T58+xfbt2wFImbRciZ8zfvx4AICtrS0GDBigF5t0gYdW1UOsc+bMkUs+7KNzjupcu3ZNXMM7d+4UXTk+++wz2NnZCaGKhg0bCrm47HpAEoaHl7N4eXllux0Ph+/YsSNP2csfKPpxjgTxCfBRO0fi4yMwMBCApLijrihTpUoVkSPy/fffC8UjPgD6RKA1R4IgCILQBZo5EkTuoZkjQXw80MyRIAiCIHSBnCNBEARBaEHOkSAIgiC0IOdIEARBEFqQcyQIgiAILcg5EgRBEIQW5BwJgiAIQgtF2iXwrhZTpkxBy5YthToDAHz33XcAgHXr1sHc3BxpaWkZjSpcOEupt0+VJUuWICUlJcv3ixcvDgAYM2aMvkwiCIJQlJkzZ+L+/fvYuXNnnveRkpKSp04iNHMkCIIgCC0UUci5evUqAKBDhw6iE4Y2pUuXRoMGDUR/NnXmzp2LGTNm5OXQeWLbtm2iQ8Mvv/wiXh84cCB8fHwU7TSQFSkpKULU+eTJk0hISEB6enqW23Mh8tKlS+PgwYMA5Ouppw3/fTt27Ijo6GgAUueGadOmiY4mtra2ihy7gPChhjUUU8h5+PAh3rx5k+XvHhERAQCoVKmSUiZ8sGzevBmDBg0CALRp0ybTe6K+effuHa5cuYK9e/cCAFavXo34+HiNbXiTBjc3N9GNp1q1avluirBt2zbRpeTEiROYMmVKrvdRtmxZrFy5EgDwzTff5GST/oXHAwICMHToUHFh6Erfvn1FJwh9YGVlJdrJFCpUSDT43Lx5Mzp16qS3TiKA1I0DAOzs7MTf6o1dAUks2MHBIct99OzZEwDQrVs32e2LjIwUDZbDw8PF62lpaShUqJBoFaTe3eSXX35BdHQ0Jk+eLF7jzXT12UgakLrG8LZptWvXRuPGjfOym0/aOb558waANEgKCAgAAGzfvh1RUVFZClbzRt1mZmY4efIkGjVqJIcpBZ64uDgAwLfffismCvPnz0fbtm1x+PBhAECvXr1E+6jx48dj6dKlerWR2xUeHo41a9YAAKKiorB///5c7ysmJgalSpXKkx38HClbtiyqVasGADhy5AiqVKkixNILFSokHN0333yD8uXLi5ZlvH0aIAmnW1lZ6Xpow3Tl+Pvvv9G9e3fxvGXLlgCk9jcvXrxAiRIlAGh2dV69erXi3aY5z549Q5UqVcTa58yZM7PtBag0kyZNAgCNC4QxBm9vb6GeX6xYMYONwB89eqRxEnK4c8yM7N7jF4Q+OHXqFGbOnIlz584BkNZp+fmnPvhYs2ZNTgOLT9Y53rlzB05OTgCQ60Evx93dXXEHwJ3N48eP8euvvwKA+N2/+OILAJq/+d27d0VHigULFshmx7FjxwBo9pwsUaIELC0t8eLFCwDSYIMPKm/evAlzc3PZjp8TAQEB4p5z69atLLcrX768GPA6OzujSZMmmW7XrVu3PE8meE6F+gArPDwcJiYmIlplZWWFhg0b5mn/2UDaqgRBEAShC4pkq6oTHBys8Xz58uUAgM8//1zpQ+vEkCFDkJaWJrI9J06cKN5LSUmBj4+PCGEqMGLR4NGjR9iyZYt4zpuNbtu2DU2bNs1y9qVP+CjzQ4J3Pp8wYQKuXLmC8uXLAwCMjY3x+PFjAEC5cuVgZmYGANi0aZMiIekPnbi4OCxYsCDTGaOjoyPatm0r1stat24tztc3b96I8OK5c+cUv44AYN68eQAynwXyGWRWGfFyzhwzC03GxsbizZs3YoZVtWpV+Pn5AYBeZ40bN27E4sWLcffuXfEaX1Jq06YNbGxsRLSqcuXKBml+/ODBA7Rt21ZEK/SJ4s7x1KlTGs8tLS2VPmSu4Bctj08XL15chPqGDBmC33//Xby3evVqsZ6nBGvXrhUJLsD7dTk7OzvFjpkbzp49iwsXLhjajFzTqlUrAFKIpkSJEjh69CgAabDzxx9/AJDC/dbW1gazsSDDl14WLlyIzZs3i9eLFCkCb29vAMCIESPEjdXQXL9+HfPnzxfP69WrBwCoUaMGevbsqXEP4oOgbdu2wdnZWVY7IiIixLoiANSpUweAdD0zxvDDDz8AANq3by/rcXOC5zJ4eXkhLCxMDGIGDx6MCRMmaNiqT65fv57hNT6QNQQUViUIgiAILRSdOb569Qq3b98Wz5s0aYIKFSooeUid4UWlFy9eBACRgbl161YR4rhw4QIKFy6MyMhIANAIPyjB/fv3xd+FChVCmTJldP4sDx3GxcWJxAK5uX//vjiONjVr1kRcXByioqIyvMcYQ1pamkjz79OnT57Ss3NDTEwMAElsgmciFy1aFL/++qtGWK93796K2vEx8NdffwF4H6rkkZThw4drLEMYkuTkZABSQku7du3E62PHjoWXlxcAZDuzVSJrev369QgNDRXPebmG0ud+TowcORIAEBYWBgD48ccfAUDvWbLa8MzxsmXLiuidhYWFwexR1DmePXtWTOEB4Ouvv84y1VvfXL58GcD7DKnjx48DkMo3eJr5kSNH4OzsLEKdNWrU0Jt9RYsWRefOnQFknhXIHSnPxDt//jwAKXS4adMmAFL6uJzExMRkue4ZFxeHlJQU8X7dunVRunRpAFLt05AhQ0S2m3qZh1LwgYyHh4d4bfbs2WINBXh/DgDK1YR+6CQlJWHmzJkar/E1+NmzZxvAoszhg/A2bdogKSlJvG5mZmaQcO+dO3ewePFisa5Zv3594RwNyaVLl3DgwAHxvFChQpg1a5YBLXoPL9GoU6cO7ty5A0C6zxlqKY7CqgRBEAShDWMsu0e+cHR0ZACYqakpMzU1ZVeuXMnvLmWjXLlyrFy5ckylUmk8HBwcWEREBIuIiGA9evRgKpWKlShRgpUoUYK9fPlSUZv69u3LjIyMMjxUKlWmr+f0kBuVSsUKFy6c6SO79/z9/WW3JTu2bt3K6tSpw+rUqaPx227dupW5u7uzChUqsAoVKjCVSsW+/PJL9uWXX+b2EDldNwX1kWvc3NwYpPpIBoA1btyYJSYmssTExLzsThGio6NZyZIlWcmSJcVvze0tXLgw69u3L+vbty+LiIhQ3JbIyEgWGRnJateuzQAIe8aNG8fu3r0rHm/evFHclswICgrSuCZsbW3Z7t272e7du1lcXJxBbNJm3Lhxwj5zc3PWt29ftmPHDrZjxw728uVLlpyczJKTk+U8ZKbXi6IiAM2aNUNwcLBIkVcvHu/atStMTU2FQEC1atXyrKyQW/755x906tQJAITywtSpUwEA3t7eeP36NQBJio0xJkJxXEpJKWJiYoRd6iUwTEshJydcXFwAQMjIyYWRkVGeCv3NzMxw9OhRvZTvXL58GXZ2dpl+X5l9j1wEICgoKDdrtZ+MCMDnn38u1uUBqfylevXqAKRlEp5xqY9QeVYEBwejV69eAKR1tO7du4tQ3B9//CEUfb7++musXLlS0QxInv168ODBbK/btm3bipKRxo0bo2jRoorZpE50dLTIuD979qzGe3Z2diKz19raGt9++y1q1qwJAHqV0Hz9+rWw8fbt2xnyGPj9ePPmzXKFzPWvkMOdoy40adIEhw4dAqB8uUd6ejocHR0BSBfT999/L9ZVVCoVfvrpJwBSvVORIkVE6r/6Qr9S8At54cKFOHnyJAApMWjixIkaqkH8pO3cuTNcXFxw8+ZNANLNnjt3uRk+fLiG9qw6OSnknDx5UtHvj0vZNWvWDNHR0ZnelD777DNMmDBByMdt2bJF1JodOHBAnBM68Mk4Rx8fH6xduxaAdNMKDw+H+j2DKzU5Oztj5cqVol5YbqKiovLk1Pz8/LBx40YAQGBgIJYtW6bo2h8vGwoKCtJwjo0bNxbnWnR0NB48eCDeq1WrlnAG6iUoSsET1EaOHImDBw+KZKbMsLe3F/9yvev8aqfqApe0e/nyJbp06aKRrMhp0KABpkyZIkcyFSnkEARBEIQuKDpz3Lt3L/r16yeyFitUqCBCa0FBQbh+/bpGj0Ke6v/vv/+icGHF9QkASKO4smXLiufHjx8XI5GoqCh06NBBzBz1DR/RpaSkoFixYpnOhlauXAl3d3fx3MXFRfZwKufs2bNYuXKlKJwHpPAQAJw+fTrLEBJjDCdPnlS02PnatWsApILq2NhYYUvt2rVFVKB79+54+/at0NZ8/PixsGnZsmW5ESH/ZGaO6rx+/RpPnjzBpUuXAEghS64dmpycDCcnJ9mvlf/++w+A1KmnX79+eVJK4bqcrVu3hp2dXQZhEjnhWZb8O+ICHtpF9REREeI6mjFjhhAjqV69Oh48eKCYfdpcunRJdCT6559/NEQLtOHXyk8//SS7YEJ2JCQkiMjYvHnzRDj41atXUKlU6NOnDwApbK6ejZ4LDCM8HhERISSRtGtWLl++DF9fXwBS+IZz8eJFvavC8LXHevXqiQsSkFRxRo0apVdbdIGvbfzzzz9ITk4W9aOhoaGKSlAlJSVprEHxi/7OnTtQqVQipDts2DBRa5iWlob+/ftrqKsoha+vL5YuXSpa6Li5uYnvJjU1FfPmzYOnp6fYfvjw4QCkeshc8Ek6x8zgN6q5c+fi6NGjWLFiBQCp6bYcDcu5YHexYsXyvOb/559/ApC6/fTu3VtDorEgcPDgQfTt2xcA8PbtW0yePFlWCTtdSU1Nxb179wAAT548wY4dO0Q4U319skiRIvD09DRYvSYXSB8xYgQCAwPFvbt69epC3nLEiBG52SWFVQmCIAhCJ7JKY2UylHLogpOTE3NyctJIF79+/bo+Dq3B+fPn2fnz5zXSnB0dHVlKSoqsxwkJCcn3PpYvX87Mzc2Zubk5MzIyYhYWFmzPnj1sz549MljI2KtXr9js2bPZ7Nmz2W+//Zarz/LPaZd5nDp1Kl82/fbbb+ybb75hfn5+zM/PjyUlJen8WV6a4+HhoVHq4uPjk1dzDF2SIXspx9GjR1laWhpLS0vL0xfy9u1bZm1tLa7hhISEPO1HG16SM2DAAHb+/Plcfz44OFiUkpmamrLg4GBZ7JIbd3d35u7uzlQqFStWrBh7/fo1e/36taHNYgkJCSwhIYHt379f43o2NjZmixYtYosWLTKofdevX2fz589n8+fPZ2XLlmWlSpVipUqVYo8ePcrNbjK9XgzqHIcPHy5uVOrOUd81VKdOnRJfKj85ixUrxsLDw2U7RosWLViLFi2YtbW1cCC5ZcWKFWzFihXCKXLHuGvXLllsPHHiBDtx4gRzdnYWF4K5uTmbO3cumzt3bo6fP3r0KCtdujQrXbq07M7R3t5ew7E1b96c7dq1i+3atSvT3yk6OppFR0ezuXPnsmrVqrFq1aqJetGNGzeyjRs35qdWytBOTnbnCIB17tyZde7cmd29ezfXX8jbt2+ZlZWVYs5RpVKxsmXLsq5du7KuXbuyTZs2ZfmZ0NBQ5u3tzby9vZm5ubkY7Nrb27PIyEhZ7JIbfr7yGk0+WC9IREVFsaioKI3Jg6Ojo6HNEpw+fZoZGxszY2NjZmpqym7dusVu3bqly0czvV5ylfXCGwI3a9YMz58/F4ksXHsUkNYOs1sUDQoKAiDp+P3xxx9IT08X7y1ZsgSAfmtqEhISMGXKFLFWxhgTdsjZpeHff/8FIJWKcNmyxMREUQOaHRcvXoSnp6coQUhOThb1eevXr8c333wji428lEG9JCM5OVk0f+ap3Fnh7e2N2NhYWWzRZvz48WjevLl47uvrCzc3NwCSFiNPppkxYwbevn2LoUOHAnifts5Zt24d+vfvDwB5bsr6MbJ582ZRszh27FisXr0awPuSoZx4/Pixxn1ALnjyjJ+fH2bOnCmkzw4cOIAhQ4bk+PnKlSsL7VB9lEnIhVIlMXnlyZMnGXSIS5YsKesxuC949uxZts3c+T3myZMniI6OFgmIR48e1Wiezv1VXqE1R4IgCILQIlfZqjwryNraOoNqAc/6W716dYYyDJ7ptHfvXpGxyIs8OVOmTMHcuXMBQKPYXSlCQkIASM17jxw5Il7v2rUrduzYASB7Ff/cwgtn1TP4Fi5cKGY233//PYD3o6KFCxeK7fbt26fxuZo1a4oOCXLNGtVtyyrL8IsvvsgwWueiAGfOnMnycxs2bBCzkvzCBcUPHDiAbdu2AZDEibnCiLGxMWxsbMT55ebmJmaI7dq1k0tg/KPMVuUi9iNHjhRqVQcPHkSTJk2y/AzPbnRxccHDhw/FDP7SpUuyl2NFRESIsoObN2+Ke5C6kDaHF9V7enqiXLlystqhBDyzm0fjVq5cCeB9x4z8EBcXh8mTJwOQIjC6KkHdu3dP2LFx40YNsYAWLVrA398fAGTrtMTL+mrUqCF62Xbs2BE3btwQmcrPnj1DQkICAMmHxMXFZTlD5P0hdWiuLV8px9GjR9G/f38NB8lvQJmFROPj4wFAI4QKSCcCnxI3b95cltTv7OA3zO3bt4sb68WLF2FiYoJx48YBkDoNKNE5hDuVLVu2ZPgecoIxhuLFi4tuCJs3b5Y9pAFAKAP9/PPPmb6fkwqO+numpqZC6Ui9NEZOeJ1YrVq1RAi8TJkyuHv3rka7r9y0/tKRj9I5cvz9/cXNNDo6Wqi+8OUGzrVr1zB9+nQAUsf2UqVKCZWrFi1ayGb0pwCvL+zcuTMYY6KbEW8Plh9iY2NRv359ANK9mJeN9O7dG61bt9a43/EyibVr12L79u0aalt8sNOtWzesWbNG9vaD3Mm1bdsWgYGBAKSBeg4+KlPKly+P06dPA9CULc0CKuUgCIIgCF3IswjA0aNHReH0uXPnMiQ+ZAUXxe7Vqxf69OkjEkuUJiIiQqg6cBULzm+//YYBAwboxQ5fX18REn3+/LkIIfPZNZ99qRfyz507F40bNxZqNErBlUR69eqFx48fZ3hfl5kj108dOHCg3r5TA/BRzxyB9+HSnj174saNGzlub21tjT179qBly5Z5t+4jgIce3d3d4erqmmmSmzYpKSlC+efs2bMwNzfHkydPAMiX9HLlyhUAQI8ePTT6wzZu3FjMHJs0aSKiMbyHLad27doYM2YMAIh/lSIkJEREJP7++2+dP9e6dWsxm121alVuZt3KKeQkJCSIjuAXLlwQqgqdO3eGk5OT+IEtLCyE4oXSIVTO4sWLAQAzZ87UiJnzNb6vv/4aLi4uerNHnVOnToluBrt27QLw3ikqfQJmx40bN0SYOSgoSHxv2TnHcuXKYfPmzSKcpkTYtwDx0TtHTkpKCs6dOwcA2L17N549eyYE8QGgS5cuAKQBnK6ZrZ8C69evx6ZNm8R11LNnT5F3wAfC3BH9/vvvGgo0AQEBYhIhN5GRkUKIfcWKFWKtMzN69Oghllpq1KihIbOpNFwO0sfHB+vXrxeZst27dxfNGdTXuwGgQ4cOea10oLAqQRAEQeiC4tqqhiYgIAAAMGrUKJG15urqKhIOsgt3EFJ9Gc9YO3PmDAoVKoQePXoAkMLpX331FQCgX79+aNOmjcHs1DOfzMyRyB985njo0CGxhHLr1i2NdlbqODg44Pjx43qxLTY2FqtXrxYzseDgYFFLXKlSJYwYMUJvDSAMjGGExwniI4ScI0F8PFBYlSAIgiB0gZwjQRAEQWhBzpEgCIIgtCDnSBAEQRBakHMkCIIgCC3IORIEQRCEFuQcCYIgCEILco4EQRAEoQU5R4IgCILQ4pPQBsqJ+/fvayjV82bH165dQ3x8PIKCggAAZmZmitsSFhYGABp91ADg1atX2L17d6afOXToEB4+fAgA6Nu3LzZt2gRAP/Z+6Lx9+xaA1Gybd5lZv369aN5NfFgkJyfj1atX4vm///6LFy9eAABu374tXgOkXq6jR48W206YMAGAfM17iQ8bvcvH8Saeb968QbFixUQn+fDwcNEUl3f7BpCnRpc5ce3aNaEJCkiOh+sLqlOpUiXs2bNHNHtVmpSUFLRv3x4AhEPOC7z11GeffSaLXepcvnxZ/O3r65vhfR8fHwBS1xWu4n/p0iVUqVJFdlvyCm82ffLkSdFx/PHjx6Jhsp+fH+zs7LLbBcnHFTB4i7UhQ4ZoaJNmpWHK3+NdcUqVKiUGnzo0x803N27cwPr168Vz3uz4/v37sLCwwMWLF/VmC0HycQRBEAShE4qGVVNTU7Fu3TrUrl0bgNS/8LfffgMg9TQrWrQooqKiMnxO6d6KxYoVE2HL169fY8mSJWjcuHGG7ezs7PTWjBmQ+mLqOmMsVqwYgIwhoL59+6Jhw4ay2bR37174+/sDkJpEX758Wfw+6qNy/jd/rlKpRMNUX19fzJ07Vzab8kpaWhpevHiBBQsWAABWrlwp+r/NmTNH9NAsVaqUwWwsyCQmJoIxJr6zhISE/2vvvMOiuL4+/l2UooCCkWIFo4ZYEztWsHdjQUOMSGKNsSdqLFEUSxIsWGKiRoOiSBQbYsOK4k9jR8CCiBXFAhYsCCr3/WPee9xdFlhgZhfN/TzPPuzuzO49zM4t59xTcjx/0aJFAIDnz59rvO/j4yOryT89PR0zZswAABw4cABNmjSh/tGiRYscrQC8rxjSlHr16lV06NABd+/ezXJMpVKhfv36VEFIYDwUnRyDgoKoZIsu+H6PNlZWVooOppUrV8akSZMASHtNgwYNMugkqC+8fIyzszMGDx5MxVIBkMlS16QuB3zvc9iwYXjw4AEAqeMyxqjjMsZoAqxXrx6qVatG+zrVqlWjElY9e/ZUREZ94VXVAwMD8fPPP9P79evXJ7O+nAuKDw1+L7Rv3x5PnjxBy5YtAbwr0J1XMjMz4efnJ5t8CxcuxLZt2wAAoaGhaNOmTaHcb8/IyAAgme3v3LlDk/bmzZthYWFB51lZWRVK+Y3FrVu38ObNGwBS0WVDIcyqAoFAIBBooahDzrNnz1CuXLksZhXO8OHDYW1tDUAyYVpaWgKQvMpy0jjlgG+Ad+jQAU+fPi0UmmNmZiY8PDwAANu2bcPKlSsBgJxGDAk3mTVs2BAXL14EIGmOQ4YMweDBgwFI2ivXHOvWrWtwGfUhNDQU/fv3ByAVd7WwsKBC11OmTIGZmVl+vvY/45CTkpJCFoC4uDhZhLC2ttbpAJdfrKys0LdvXwDAihUrZPteuZk8eTIA4Ndff0X58uXJua0wmVDv3bsHALhz5w7q1atnZGkkB05XV1eymkVHR9OcISM6+7OiZtUnT57Azs4u28lx/PjxOr0Y27Vrp6RYAFAofnhtTExM8MUXXwCQJsfY2FgAwO7du7Ocy02uSnWs4sWLA5DCQfgCasqUKVnM3YXJC1UXMTExZL53cnLCli1bCu1EXhh59uxZtpOiubk5HB0dc/0O9YXvsWPHZAuT6dq1KwDJf8EQY0ZBOHz4MP744w96PWTIkEI1KQLAo0eP0LlzZwDAxYsX4evri0ePHgGQxhf1PwAAIABJREFUvGuPHDmS7Wdbt24NAChbtix53Pfu3bvAMi1ZsgS3b9+m19WrV9cwQQPv9ourV69Onso2Njbo0KEDnVO5cmUaM/XdQlFkcnz9+jUAwMvLi+LvtOFu84WBwMBAcsYwJowx2t8DpL0U9b/q2NvbA5BitipUqKCoXHlxkOJ7jurPjb3nyKlcubKYGPWE7/GsXbtW430nJyf4+voCABwcHIw6KZ0+fRoAUKtWLbK4FFZ69+5N2vLUqVM19r6NzY4dOwAAI0eOxI0bN+j9CRMmkPOVhYUFPv30UwDvFsR8ctf2e+ATakG4cuUKgKzhYqmpqRox6YwxCgE8evSoxrnqYWcAUKRIEQCAh4cHxbLnhNhzFAgEAoFAC0U0xx9//BEAclTDExMT0bJlS8yePRsA4OnpqYQoevH27Vujta3O06dP8dNPP+l1Ltcwp02bBj8/P8VMNKVLlyaz6uzZszFr1qwcQzn4udrPXVxcaHVvyLAOHkwNvNO2Bblz4cIFAFLYhTqWlpaoU6cOvX7x4gW9b0j2799P4Vhdu3bF8ePHAUhB8+bm5krsS+UL7jeQmppK183DwwMbN24kjWfv3r0an7G1taVkGkqbXhMSEmhP/vHjx+TFz7d3uMnS0Nsn/P9PSUmBqakp1qxZA0DygcirZpqWlobt27ejUqVKAKBhbs0J2R1yAgICMHDgQL3PNzU1BQBs3boVnTp1ymtz+YY7ktjZ2aFbt24IDQ2lY9HR0QCA+Ph4ODg4kEOC0jx58gSlSpWi10WLSmsXExMTDBkyhDalU1NT6WZhjGHatGmYPn26IjJFRkbSHgKf8PIzOaqfGxsbi2rVqikiL4engvvhhx/oHktMTJTL8eqDd8j5/vvvAUAji4sumjdvDgAYN24cWrduTXvVSvP48WOKn05OTqbQB0dHR5iZmdG+VLFixRAUFATAsGEAAHDu3DnKrpWRkUHOX2ZmZnj27BnJWLJkSaSnpwOQFsiMMXh7ewMAxYUrwb59+9CtWzcync6aNYvS6Skda54bXMHy9/eHu7s7mX4Vur9EhhyBQCAQCPRBdrOqLs9U7lXWuHFj8hR68eIFBg0aRGaZX375xaCaI9fKnJ2dsWPHDpQsWZKO8VVceno6ihYtil69egEA/vnnH0VlKlasGJlhAJDGylfI6vD8oIGBgTh27JhiMjVv3pzaunTpEiIjI7M9t2fPnpScQJ1Lly7Bzc2NtPXNmzcr6pBw4MABSiKdnp6Ojz76CADQo0cPAECNGjUASBlyBFl5/fq1zsxVuuD3Q2RkJLZv344uXbooKRpha2uLkSNHApByMTds2JCOXbhwAbt27QIgWTS4Z/qUKVMwbtw4g8h3584d9OnThwL/gXdJAOzs7NCmTRsKKXJ1daVtkvr16+P27dsaFiSlmDdvHl69ekUex2fPnkWbNm0ASBa9Hj16UMauQ4cO0ThuiH7Dx2dAyoHM+2yXLl0oeULv3r1hYmJCmq/cyG5WzczMREBAAACpkw0YMIDMWtqq+owZMyjtE/Au4Tg34xmCJ0+e4IsvvoCzszMAKWl306ZNAUjeTcuXLydzzOXLlw0mV27w5OLNmjVD0aJFERMTAwCKe67ml/DwcFr81K1blyojyE18fDxat26t4f6dHRUqVKAYTp5uTE8+aLNqSkqKzr0uS0tLcocHpAT+6tVj7O3t8e+//wIA9Sdjwe+vnTt3YsmSJQAkL8oaNWqQu7+Dg4Ni7f/+++8YOXIkjXkNGzbElClTAEgTYHbp6mrWrIkLFy4gIiICgLJj4Zw5czB9+nSKLgDe9YMmTZponBsdHU0LpvXr1yvuI8Irq0ycOBEbN27MNi7W0dGR/Fa+/fbb/DaXfWb6HB6K4uvry1QqFT0OHTrEDh06pHSzevPmzRvWrFkz5uLiwlxcXIwtjk5q1qzJVCoVmzBhApswYYKxxcmWU6dO0e/coUMHxdoZMWKExj2lUqmYjY0Ns7GxYe7u7uyHH37QOJaSksJSUlLy2kxu/aawPvTi6dOnrGLFiqxixYpMpVIxd3d35u7uzk6fPq1xXlhYGLO1tWW2trZ0PX/66Sf2008/6duUQXj06BF79OgRa9WqFVOpVKxGjRqsRo0airYZHR3NlixZwvbs2cP27NmT6/lxcXEsLi6O2draMkdHR5aYmMgSExMVlTEv+Pj4MEiLK7Zy5UqDtx8eHs7Cw8NZcHAw++6779h3333HypQpQzIBYMuXL8/v1+vsL2LPUSAQCAQCLYxa7DinUI/CQEBAAI4ePQpXV1dji5Itffr0gY+PD+0LFlbUK3bwvT8l6NixI1avXk17nx4eHvjuu+8ASEkArly5An9/f8Xa/xAoUaIEhRQdP36crpf2fnKXLl2wYMECANCoi6kkPLB78uTJ5AOQWxUVfnzjxo0a6RCVpFatWqhVq5be53Pv6idPnqB69eooV66cUqLpzatXr6iCjb+/Pz7//HMAoNAPQ6KebIKbdJs2bQovLy8aVw4dOoQhQ4bI1qZRJ8f4+Hh6XqVKFY1N9cLA5s2bYWJiorOor7HhuU8Lo2y66NevH4V26HLakYtOnTplW+0FkPZLOA4ODrQfLtCEh3Lwv9lh6EGcOwBZWFjkOZbxo48+KjTxj+pkZmbi2rVr9Dq3a660LACwa9cuzJ07lxQYFxcX2qs1dp/Zvn07ANBeI4c7TsqFMKsKBAKBQKCF0TTHHTt2kGs/AAwcONBgAcS5wbNtnDhxAu3bty90tf5evnyJfv36AXhXq9CQYTB5ZcuWLYiLi6OVnbFyrYaGhmL27Nnk+r1v375CqUkYg5iYGMpnmZcVOM+kYwgePHhASQmGDx+u4e7/PrNr1y6EhYUBkLK3KKE58lyiHTt2hI2NjcYxnnFm165d5Nl78uRJ2NjYkAlz3rx5BgkvyQ5eLWTFihX45ZdfAEhhWra2thSeI/e4YvC7i1eY8PT0xIsXL8heXJiKe/JQlMePH8teveP8+fNkFujSpQsl7VUvZKyLN2/ekHvzoEGDqDMBkj2eZyopTPD9oWHDhoExRqmp5ILH1Pr4+FDowcCBA7OEIZw7dw6AtC+mUqkoa0lhW/QYEzc3NzJH16hRg8IOcqqssHLlSirDZAgePHhAibEjIyNpEuEJpXNj8uTJOH/+PNzd3RWSMG9cvXoVANC3b18yT8+bN0+RtviEcvjwYXz55ZcApG2tbdu2UdhIWloaLRyHDh2KGTNmKBruok7//v0pK06RIkWoz165cgW7du2i0Cx1hapkyZJYvny5LNU/dJGnOEceWB0fHw83NzfKUZfbIMPt6Xv37qXAVz6w8ZXJ6tWr81tbT1aOHDlCgbDVqlXDgQMHZNkj4wNP3759sXPnTnqf36g5pdy7dOkSduzYgX379mU5Vr16dYSHhxeKDXx1Ll26RINQcnIyXFxcqIqCXBYCvtDiZXYAYP78+Rg7diy93rBhAwWLP3z4EB06dNBZAiyPfHBxjuoOU8C7IOxy5cqRQ4ujo6NG1ZX79+/j1atX9NrJyYmC75VKD9i+fXsAktbP0zzmNP68fv0ahw8fBiANwOnp6ZQqUom0kDypya+//oqxY8dmq22Fhoaie/fuAKRrzdOj8f9PbubOnQtACuDnDoYJCQm4du0a/VZubm604DB0LlXt+y87ypcvT7/38uXL5YrrFunjBAKBQCDQi+wCIJmOoOESJUqwEiVKUMAvDwBeunQpu3r1apaHv78/a968ObO2tmbW1tZZgrN9fX1Zeno6S09Pz2/wpt5cu3aN7du3j+3bt4+9efMmy/EjR46wI0eOsAoVKjArKytmZWXFdu3aJVv7UVFRLCoqKss1yO/DwsKCWVhYsM2bN8smI+fw4cNsypQpbMqUKezGjRt6f+7ixYusR48erEePHkylUlFwrkqlYhcvXpRdzrS0NJaWlsaqVatG18Xa2ppFR0ezhQsXsoULF7LSpUvTseHDh7OMjAw5mjZ2ML/sSQDq169foPvR2dmZXbp0qQCXVD9WrFjBVqxYQW06OzszPz+/LOddv36dXb9+nf3zzz8ko52dnc5z5YQnMlGpVGzs2LE6z5k7dy71C5VKJes4876yaNEi5uTkxJycnFiFChXYZ599xj777DM2btw4Nm7cOEoCkJqaqkTzOvtLnsyqPOalIPsMfI/N398frq6uWao6K0WfPn0QEhICQFLNtVV4nhopIyODYrfUzXMFhW96+/v7057m3bt38/VdrVu3pmz9cppTHz58CEBy7uH7hfb29mS6qFatWhZT1NatWwFIptPLly+TWUmlUpE5eu3atYoWxX3x4gXtO+zZswflypWjDXwrKyuK2Zs4caJcTX5wZtW0tDT6Lbmzlz7wazt58mSDODfx7Qlvb29s27YNgGSWrF69usZ5PFdpUlIS9fV169ahb9++isrHHVpGjx4NOzs7DBs2DIAUM6juy1C5cmWK06xVq1auPgcCRRFmVYFAIBAI9CFPmqN6JYixY8dmmwxWG14VoW7dupg6dSoAZTbDc+LUqVPkJXrnzh16/8aNGzh06BBlff/pp5/ISUipYFeuMZ48eTJLodP9+/cDkDzZeHHenj17okmTJqhduzYAyZtQXw+9vKCuOXLnmZzqMup6zjfyW7RogcDAQNllzA6uUdSrVw9Xr14lp4M//viDMnvIyAenOQKg35lr/4BUX/D333+n1w4ODhg0aBC95l7mStyPOZGWlobffvsNgBSCwO9XbaZNm0bam62treJOf7wgQPPmzfH8+XMNCxUPofDy8sKiRYsUlUOQJ3T253xX5bh69SoOHjwI4J3LvjZVqlSBm5sbDfLGztQv0I/IyEjKJHPp0iXKksEnR27CunjxosbzXr16URosJbPgFAI+yMlRIB/btm3DtGnTEBsbC0CqGMFNuq1btzamaIKsCLOqQCAQCAT6IHs9R4HgP4DQHAWCDwehOQoEAoFAoA9ichQIBAKBQAsxOQoEAoFAoIWYHAUCgUAg0EJMjgKBQCAQaCEmR4FAIBAItBCTo0AgEAgEWojJUSAQCAQCLYoaWwBDERcXhy1bttBrntO0Xbt2aNeuHerVq2cs0d47OnXqBEAqNuzt7Q1Ad3FUntO0R48eehUyFQj+C7x9+xZPnz7FunXrAEg5X3nB7nnz5mHPnj04d+4cAKmAdGRkJADIVdj3P8PNmzcBAOHh4bh48SJatGgBQMpVrQ9CcxQIBAKBQAuDp497/fo1ACnbf2hoKGkUR48epXpnjRo1otp7Xbt2lSXj/9atW9GrVy+dx0qWLImZM2cCAEaMGFHgtpSCX6uqVatSHb2BAwcaXI4uXboAkKohaGNpaQlAql/Hf7ebN2/CwcHBYPIdPHgQbdq0AQB4enpSEnUZeV/VYFn78/nz5ykpfbdu3eDk5KTX50JDQ6kIAa/vagjOnj2LW7duUW3Vffv24eLFiwCA6OhoVK1aFQCwadMmqoAjF/Hx8Zg7dy4A4MmTJ9i0aZPenz1x4gQAoEGDBrLKBEg1LpcvXw5AGoP1wdXVFeHh4ShRooTs8sjFqVOnqIYsrx5VqVIlAEBCQoL26Tr7s+Jm1WfPnuGbb74BIBUg5aWFoqOjNUoeAe8G/6dPn2LSpEkApM7D/6mCwAs1A4CdnR2aNm0KQMqe//TpU4waNQoAcOzYMaxZswaAciWr8so333yDqKgouj4JCQn4/vvvAUjm4m7dulF1jFKlShlUtpEjRwIAPv74YwDvCuXu2LGDCjEbcmIEgJo1a9K12rBhA/r06QMA6N69O169eoWwsLAsn3F3d4ednZ1B5XzfePjwIU6fPk3bE9u3b0dycjIAYOPGjWT+08WNGzcASFVe5syZQyYvXpRaLv7991/4+flh9+7dWY69efMGb968yfaz8fHxAOSbHFNSUjB+/HgA0iSUU9vZ0a5dO1SpUqXAsuhi+vTpmDNnDikspUqVyvJ/c5nVJ86KFSsWmrFRnbS0NBp/wsPD8fLlS43jvGKQvgizqkAgEAgEWiiuOc6cOZNWmtpOGdWqVUP37t0BAE2aNCGzhouLi+xypKam0vOPP/4YwcHBACTT0Ndff02qdnBwMD799FMAUqHUwsD169cRExOj8R5f0c2fPx/z58+Hm5sbAKBs2bJ0zvjx4xU3W3l4eACQiruqwx11CgN+fn4AgCVLliAmJgYpKSl0jG8reHt7k1lf8A7GGDmLpKSkaBQVVrf8REdHo1OnTtkW8e3RowcASXOUmxcvXlDx9AsXLpAmlB3cyqHt4NKhQwcAwI8//iiLXH/++SdWr16dr8+2bdsWALB+/XrY2trKIo829+7dw+vXr9GtWzcAwN9//02F6Tm8wL26hl+mTBmDO9jx8U6973K4lXHjxo0a2iKX0d7eHmvXrkWrVq3y1Kbik6P6zWFtbU1muF69eqFGjRqKV+bODnNzcwBAw4YNsX//fqxduxYAMHXqVDIVvU8cPnyYntesWZPeM+SeTmGBeyJz/v33XwBZF2fqKDUAva/wRcPmzZsRHh6e6/nPnz9HeHg4LWy1rzX/PjkHVV5sfdCgQbh+/ToAwNHRERUrVsS3334LADTwq8P3yqysrGSTRZuVK1dizpw5Oo+5urpi3LhxqFy5Mr3HFx1DhgzBpEmTMG7cOACAjY2NYjJyJcDCwgIAskyMAGBiIhkX1RfdxiA6OhqAtMi6ffs2AGTZllOndOnSmD9/PgDAy8srX20Ks6pAIBAIBFoorjmeP3+eVh1ly5bFrFmzlG4yV8qXL6/x2snJCT///DMAoHHjxoUmnohfq1OnTmm8P3DgQEydOpVex8bG4vHjxwAkB5Q//vgDAMgh5r9GaGio3udysz73VhZI/P333wAkTUYJsjO/5oX+/fsDAO7cuYM6deoAkO5/vj1jDPh1GzlyJNLT0zWOcbNtSEgIeXVzuIWnffv2sLGxUVSrfd948+YNxYRyrTE7eETCL7/8UmBHJsUnx6tXr9JzHoRpDOzt7REXFwcA6Ny5M3nNWltba5zXunVrg8umiydPnmDevHkAQJ2My/rjjz9qTODqz/v27au4bHz/aNeuXQgMDAQA1KtXD8WLF1e87dw4e/Ysdu7cCfUQJf7cyckJI0aMIHMWnxgFWdm8ebNi371q1Sq6h+SC34fGnBgfPXqEBQsWAECWiVGdBQsWoFevXjR4m5qaknlQe+H+XyctLQ1169alsbto0aJwdXUFIPXrpk2b4ocffqDzucmcm4oLguKTo3onyy7O0BCMGTOGXM0HDBhAnalmzZoUM8gpU6YMgHf2dmPg5+dHEzgnJCQEgDIOS3mhYcOGAKQbcdWqVQCkRdD48ePRsmVLAECxYsWMIltCQgLS09NpsAkICKBNfCsrKzRu3Jj2ZAUFo2rVqln6CHfgqFGjBi1KLl++DH9/fwDSnmO9evVQsmRJWWVJS0uT9fvyAv+fAwMDKW5SF3v27KG/Pj4+9H7//v0pJu+rr74yWjapW7du4ezZswCkePR27drJ/jvlRRZAinOPi4sjH5EhQ4bIYnXQB7HnKBAIBAKBNoyxnB4FZsCAAQxSZg7WtWtXNmDAADZgwAD27NkzOb5ebxISEpiLiwtzcXFhKpUq2wcANnToUDZ06FC2atUq9ubNG4PKeevWLXbr1i1WrFgxZmJiQg9XV1eDyqEPJ06cYJ6enszT05OVKFGCqVQq5ubmxtzc3NiJEycMKsvr16/Z69evWZs2bTSuW6lSpVixYsXoetrb27Njx46xY8eOsdevX+e3udz6TWF96E3Hjh1Zx44dNa6l9sOY3L9/n9na2jJbW1sGgDVq1Ig1atSoIL9pvomLi2NxcXE5jiv6PlasWMFSUlIMIre/vz8DQL9n0aJFNcbBokWLsho1arAaNWqwgIAAg8jEGGOvXr1iLVq0YC1atCB5mjVrxpo1a8Zu3bqlRJM6+4vik2PHjh1pclR/1KlTh61du1aOJvTm+vXr7Pr166xq1ao5To7qr4cOHcpu377Nbt++bRAZb968yW7evJllIPrkk0/Y+fPn2fnz51laWppBZMkLQUFBrGbNmnTdypQpw06ePMlOnjxpkPZjYmJYTEyMzkGcy6T9/oULF/LbnLEnOUUnxzVr1tCgmNNA7ubmxp48ecKePHmSx8snD19//TX7+uuvNcYVV1dX5u/vz968eWOwhe3ixYvZ4sWLs1wfe3t71rx5c9a8eXMWEhJCz+vWrZvjda1duzYLCgpiQUFBisrNJ0f+sLW1ZWPGjGFjxoxhM2fOZM7OznTMxMSEBQcHs+DgYPb27VtF5UpNTWWffvop+/TTT7NMjgqhs78Is6pAIBAIBFoonng8JCQEZ86cASDl57tz5w4AKRm1paUlLl++DKDwhB1MnjyZ5OXB5DyJ9b59+xRvnzvhfPnll1mCr/lvNWXKlEIZepCcnIwxY8YAkHLWcs+x2NhYxXO+xsbGAtCdyJp7SRcrVkzjmsbExFBO2jzyQSYe505qQ4cORUZGRu5fxhiVLwsICDB4blqeuGP48OEazmvm5uY4efIkAMieQFwXPCPPzJkzKVj9yy+/RL169fDJJ59kOf/ly5c4e/YsJcQPCgrK4nzHQzmWLVummAd6QEAABgwYQK+/+uorjST9T58+peQiX3zxBb0/atQozJ8/H0WLKufPmZSUBEAKf+HXlMNL4YWGhuoslZcPdPfn7FRKJpNZVZuXL1+yly9fsm7dujEAzNfXl/n6+irRVL5JT09n6enp7PDhw8zW1paZmpoyU1NTVq1aNZaQkMASEhIUl2Hr1q1s2LBhbNiwYczT05OpVCoNO7ylpSWztLRk//77r+Ky5Ic5c+aQSeTIkSMGa3fu3LmsQYMGbOnSpWzp0qVZ9m/s7e1Jrj///DO/zRjbPKqIWZWbUtVNz46OjtnuOaqbqrt3757PS1lwHj9+zCpUqMAqVKhAZsBWrVqxVq1asbt37xpNLn1JSEhggYGBLDAwUGMbQKVSMSsrK7Z+/Xq2fv162dt99uyZhul006ZNWc7he/nbtm1jVlZWzMrKigFg8+fPZxkZGSwjI0N2udRJTExkXbt2Za6urszV1VXj2jg6OrIzZ87I0Yxx9hyzY9u2bQwA8/f3Z/7+/ko2VSAOHjzI7OzsmJ2dHVOpVGzr1q1s69atBpUhLS2NxcTEsJSUFJaSkkKdyMTEhE2ZMsWgsujLmjVr6Cbu2LEjS09PN7ZIjDHGHBwc6NoV4L4z9iSnyOSoa292yZIlrE+fPqxPnz45To6lSpVihw8fzuflLDjJycksOTmZVapUSWMfbfr06QaVIykpiSUlJbGGDRuyYcOG5fnzY8aMybIH+fnnn7PPP/+cPX78WHZ5t2/fzvz8/Jifnx/LzMzM8dyAgAAWEBBAvhlXr15lV69elV0mXSQmJrLExEQ2ePBg1rhxY9a4cWMGgFWrVo0dOXKkoAtwsecoEAgEAoFeZDdrMoU1x7t37zIAzNvbm3l7eyvZVIHhXlrG0hy1iYyMpBX7uHHjFPceyw/qmqNKpTKYe3pOhIaGsqJFiwpv1ez+qf/XtlQqFXNwcGAODg4sKiqKjl+4cIE5Oztn69m9ZMmSvF5H2bl37x6rWrWqhva4c+dOtnPnTsXbTk5OZjVr1iSv7T59+rC3b9/mqX9mZmay4OBgZmZmxszMzDSub340USWwsLBgANi+ffvYvn37DN4+94Ln9x/XJAtg4tXZXxTPkJMdfMNZPTN9YaV06dL0nBfMLCypxxYsWIBRo0YVmnywhZmwsDBkZmZSpQPt/Jb/dXjWlpkzZ+Lhw4cApFyfvFyRnZ0d7O3tKXsJIG+VDTlwcHBAYGAgVeW4fPkyRo8eDUDqxzy7kxI8fvwYFy5coNchISFo3749AGg4vuSESqWCp6cntm/fDgD4559/6FhkZCSVZCoMqRpzy3OqFA0aNAAglapSL2IvN8KsKhAIBAKBFkbTHGfOnAkrKyu9V1TGhGfaB+RfLXE38ISEBKqvlhvqFTkKK1FRUfS8f//+iudo5MWrv/rqqyzHeHWTDRs2oFixYpSj1snJSVGZ3jd01fN7+PAhhWtoFztWp1y5cujataui8umLq6sraRTdu3en4gc8jEwpzM3N6T5/+vQpgHeFttu0aaNX2MHbt2/xv//9D8ePH89y7P79+1T01xg8ePAAwLuQMjkLSRw5coR+n969e+sVJsLHmGvXrgGQrp2pqalsMhl8cuTxaCtWrEClSpUKTXyjOjwDfGZmJhYuXEgJg5UgMTERALBu3bpcy3nxwUd94unTp4+G2VcOjh49ioCAAACgxOL6sHHjRsyePRuAVPGdxxDOmTMHRYoUkVVGQKoADwD9+vXLtprKrFmzaDGhUqng4uKS54rg/xX4YGdnZ0dmVQB6FTu2tLQ0yGKDT3qjR4/OMbl9o0aNFJdFmwoVKpA5d+HChQCAK1euAJCq/QwePBgAUL9+fY3PxcbGYvfu3QCk8kwHDhzQ+f2jRo2i2GFDwxiDr68vAKniiLW1NSUDLwgODg4AgNTUVKqokpCQQAsy7TjR69evUwGL+Ph4qFQqKokod6GIAk2OPIC/adOm6NOnDwDNunhmZmYawcQBAQF0PCMjQ69OpzQ3btzQyJAPvLPzc61OHf5/ytU2D67VVbGcs2zZMty6dQs7d+4EAFSqVAmTJk0CIA0CclfA2Lx5M1avXg0AaNmyJTp37gwAWLNmTZZzeQX2devW4dmzZ7Sy9fT0xF9//QVAub09XoNz+/bt+P333+n906dPY8KECfSc74u5u7trWAEEmvAECp07d6bFUU5wDQIAVd1QmqVLlwIAIiIi8OWXXwIAPDw8spSe49qEOvokNigofHw7evSohpadkJCAiRMn5us7+cJv0KBBBRdQB1zL1bbuvH79mqqMjBw5kqoaWVlZYf369bKU1+IT28OHD0mlKq4HAAAXLklEQVRxio2NxbRp0/T6vJWVFY2dZmZmBZZHHbHnKBAIBAKBNtm5sTI9XL95thv1hNNQc+8uXbo0vQctt+9ly5bl1+1WVoYOHcrMzc2zdU9Xf5iamrKwsDAWFhYmS9uNGjWisIJixYqxxMREdujQIXbo0CH25ZdfMhsbG2ZjY8PMzc2ZiYkJVRWJj4+Xpf3s2LBhA/3PFhYWlI0nt4oC3377LSV3N0RydPXgdB8fH+bj48M+//xzZm1trRGs3rt3b9a7d2926dIluZo2dkiGIqEcnFOnTjFHR8ccs+PwJAAHDx5kBw8eZC9evMjjJcwfjx49Yo8ePWJff/01yeHs7EzZo/hDvWIHD4swZML+efPmsVatWuW7OgdPPDJz5kyWlpYmq+w8HK1OnTqsTp06zMvLi3l5ebHExER27tw5du7cOebn55clqXupUqVYqVKl2K5du2STZcuWLWzLli3M0dExz9eoVq1abPPmzXKIobO/yJJbNS4ujswJQUFBWdy7eRsqlQpeXl4AJFOhsQriahMWFkbmTcak6tKApN4PHDiQckaWKVMG3t7esrW7Zs0aDYekBg0aICEhAYBUVZxTpUoVFC9eHJs2bQKgfPgLY4xcyc+ePYvQ0FAAQHR0NPr06UPFlitWrIj+/fvT54oWLWpQ135eAXzRokUa9xggFdsFJHMQ3+uRkcIVv6A/eudK5tfs6NGjePLkCQDJIcPMzAzOzs4AJFMq36c0RmgB7weJiYk5mky3bdsGQDM/qCHIyMigfXF/f3/aptm5cyeZEAGgVq1atMcGAG3btqV9SSX2GHm+2ZiYmBzPMzExISctDw8PzJgxAwAUyaF7//59ClPR5q+//tIoZs1zq3bv3l0uRz+d/VmYVQUCgUAg0EL2qhxJSUnk3RkSEoKoqCjyHOvQoQNtKivhvfi+kZSUhA0bNgAAfvzxxyzHFyxYAEDK8O/o6GhQ2d4H+Krcy8sLjx8/BgDUrFkTxYoVI2cdhbz7PnjNUZ3z588DkILQbWxs0K9fP1mFKiiXLl2iSjoLFizAuXPnKBRg0aJF+P77740pXqGDe9D+/vvvCAkJoSQP6nTv3h1eXl7o2bOnocUzBjr7s+IlqwSCD5D/1OQoEHzgCLOqQCAQCAT6ICZHgUAgEAi0EJOjQCAQCARaiMlRIBAIBAItxOQoEAgEAoEWYnIUCAQCgUALMTkKBAKBQKCFmBwFAoFAINBCTI4CgUAgEGghW7Fjnr4rKCgIW7ZsAQC8fPkSN27cgI2NDQApKXSzZs00PscTkctZVVqgHNOnT6fnPBGxOu7u7gCAQ4cOGUiivHHq1Ck0bNgQADB8+HCNOpCC3MnIyMCYMWMAAMePH8e5c+dy/czNmzfx9u1bel2yZElKaC0QFFZkSR+3bNky/PbbbwCkAr55wdTUFICUA3HYsGF5+qxS/PvvvwCkTPrqmeJjY2PRo0cPAO/ynhY20tPTKX/t1q1bcenSJQBSlfL8widEXZNhduRyX8lOdHQ0AFBeX74IO3r0KFauXAkAuHXrFhhjVB3BxcWFrk8e+U+mj3v79i3GjBlDBYc///xzzJ07l47Hxsbi4MGDWT63d+9epKen0+vRo0cbrDhyYeHatWt49uyZzmPW1tawsrICANjb2+Pu3btUZHjt2rWoVq0aAKB///5UHFggKyJ9nEAgEAgE+iCLWfXQoUMaK0PO+PHjqfaWLg4cOIDr168DkFZPxiIpKQnh4eEAgE2bNuHw4cMAgOfPn2c5l5vhBgwYgJo1axpOyFw4deoUACA8PBxBQUEApDpo+dUYIyIiAAAtW7bM9hx3d3e4ubkBkLTLiIgI+pyh4bX6bt68CQAwNzcHAJ33Jadx48bKC/YBcfr0adIaASAqKgpt2rQBgDzV8eS1Ng3FsWPHAEhWBOCdFeWrr75StN0rV65g2bJlAIB169YhJSWFjjHG6Jp99NFHZGZ2cnJCXFwcbt26leX7KleujN69eysqc2GFb9udO3eOrENz587Nct81aNAAANCpUyf4+PgUqE1ZzKpv377F1KlTAQC//PILPv30UwDSP2JhYVEgAZUmIyMD3bt3x+7du/U639XVFQAQGBiIqlWrKilaFn799VcAQEJCAv766y8AwOrVqxEWFkaT+8uXL2n/dtmyZfRb5IWIiAidkyKfDNX3HQsL5cuXBwDcvXtX4/2KFStScdYGDRqgbNmyZL63srKiSTSP/KfMqq9evQIA9OzZE3v27EG9evUAAKmpqWQ+//bbbwEATZo0AfBukNKFhYUFTEyUMVqFhoYiJiYGixcvpvd4oVxe4szMzAyAVM6M+zzMnz9fdlliY2Px2Wef6TymPjnqe8zNzU2n2fpD58yZM7T4TUpKovfLlCmDtLQ0Ksatjr29vca5uSDMqgKBQCAQ6IMsZtUiRYqQY4OFhQXmzJlDzws7NWrUwNWrV0nWIkWK0AoTAKpUqUKmjBYtWqB9+/YA8mZGKiiPHz9GkyZNkJCQAAAoV64cunfvDgDYvn07gHdmRCcnJ+zfvx8AqOBrXsnONOrj40PeqIUZHx8fDBkyBIB0XbjTlzFN9+8zW7duBSA5OxUvXhx//vknAKB+/foGl+X06dMAgD/++IMc59S5fv16jqZ0QLIWAUBycjKWL18OAOjWrRttEcjFpk2bCvwdTk5ONP7oKoiuJNevXydzpjrXrl3L8h7XaOPj47Fv3z5Z5Vi8eLGGFjh+/HgAwHfffYfnz5/r1BC5daAgyGJWTUlJIbNWx44dKZTjfcDGxgZPnz6litf+/v60r1iuXDmMHDlSMRNQTrx9+xa//PILAGDp0qW4f/8+mbDUJ2ZTU1PUrVsX7dq1A5A3j9LsyM6sCmTdZywsqJtVL1++jE8++UTJ5v4zZtXk5GTqG0ePHoWvry9+/vln2QXLjX/++QfLli0jL87k5GS9P8vvjXLlygGQ9u4AYOjQobRw4tslcnLt2jVUqVIly/udOnXCjh07ZG8vv2RmZgKQPGN53962bRt8fHzIs1sdbmZXh4frWVpa4vbt27LJlpaWhvbt2+N///sfAOCnn36Cr68vgPwv/nUgzKoCgUAgEOiDLJrj0aNH0bx5cwCAr68vOecUZuLi4gAAtWvXRqlSpcgUUFg8UCdOnAg/Pz+N99Q1x06dOgGQHE7++OMP2dvnptWIiIgctVHuEebu7m5Uk6u65rhp0ybSdhTiP6M5DhgwAKtXrwYgBe/fvXsXxYoVk1uubAkJCQEADB48GKmpqdmex03m9vb2ACRnGwCYMmUKOaVVr15dSVGz4Ofnh0mTJmV5PykpieQsDHCHllKlSmHEiBEApPFx3759qFixIgDJ+aVjx44AJC2Re4wCQN++fUnjLEg8tS46deqE8PBw+v69e/fKqTFydPZn2VtZvHgxbG1tAQCtW7eGk5MTihcvLnczBYZfYJVKhWfPnslio5aDyZMnA4BGcHXRokWxbNkydOnShd4rVaoUHVMCPtG5u7uT+XT69Ok4fPiwxp4knzhnzJhhVJOri4sLAGly3Lhxo87J8ejRoxru9ADI85JPrgKJN2/eAADu3btH740YMcKgE+P27dvh7e0NIKspr1evXmjUqBG95hOgeh8xNtqmX56cg5sgCwvqe5nc92LRokV4/vw5Pv74YwBA8eLFNXxIRo0aZRDZdu/eDZVKRd7P2tfU1NRUsWxLsmiOr1+/RuvWrQEAkZGRGsdq165Nq7iePXti7Nix+RJUKfr374+1a9dS+MPBgwdRpEgRo8nDY+9OnDhB77m7u2PPnj2FZgJX1yp5TKguJx4+wRrCkWfVqlUAJA3D1tYWnTt3BgA4ODiQI9PBgwezaB88k86RI0fy0twHrzlOmDABADBv3jx6z8nJiQZLQMqQw7UJHu8oJyqVSm/HN27x4Y5q2TFmzBhaWCrJyJEjsXTpUg35Z82aBUD3QoxP6lyxMCSVKlUCIMUIX7hwAQAoK4+xMTExyTHkxdbWFgEBAQCAtm3b5nfxJvYcBQKBQCDQB1k0RwCUWPjUqVOUjPjkyZOIiIjQyLfKvcM8PDzQs2dPdOvWDYA8rrf54fnz5xou/hMnTiQvUWOwbt06AJIGpO6S3qRJE7Rt2xYAUKdOHdLEuFZeGFDPkKO9T+nj46OoqfX+/fsApGujbgrMDR4C4+fnh5EjR+r7sQ9ec+R9Qj2sSRfcrF++fHl4eXmRJyvv5wWhefPm5KUoF2ZmZqQpTZ48mZIAyEVsbCx9944dO/QO9OemQVdXVwrPMhR8DN6xYwflKDa27wXP+NWoUSOoVCqULl0aAFC3bl2aT169eqWRSWjbtm3o2rVrfprT+SPJNjlmR0pKCqX02rJlC+2l8VgjXiHBx8eHTDSGjCFMT09Hs2bNKH7KwsICUVFRAN7tYxmDhIQESnLOO5y6Qw53S580aRK+//574wiZA+qOPHzCNETFjmXLlmH9+vW0QFMf3EuUKIHatWvT67S0NJw5cwaA5OafBxf0D35y5Ga1R48eYeDAgQAkE7U6UVFRFLbFzdUTJ04EAFkWmDt27MA///yj89ipU6cQHx9foO83NTXF8OHDAUiLUTlMibyvNm3aFKmpqXnOggNImXB4uAJ3dFQSPhF16NCB4rjXr1+veLv64O3tjU6dOtE8UalSJTx8+BCAtC++ePFiclz08vIi57E8IsyqAoFAIBDog+KaY3b4+voiJCSEVlrAu83/gQMHGtSjKyMjg7wbd+7ciQEDBgB45+RhLLhnVlBQEKKiovD06VMAUh09ddNhcHAwPD09jSKjPrRs2TKLw47SJa14kml1zdHGxkbDw/HAgQNkqhaaoybcpJ+cnExWCl3w/rtkyRIEBwdT0PjIkSOzhCLJye3bt/Ho0aM8feb48eNYvnw5zp8/n+VY2bJlkZiYWGC5+PVo1qwZUlNT4eTkBEDTQ7Vhw4Zo3rw5aUAzZszQKGfFGCOr1cmTJw2W2WnFihVkFo+MjDSq5UxfVq1aRdmw6tWrR1YpS0vLvHxN9up9Dg9Fef78OVu5ciVbuXIlMzU1ZZA6L5s7dy7LzMxkmZmZSotABAcHs+DgYAaAlSxZkpUsWZIlJiYarP288ODBA+bs7MycnZ2ZSqViwcHBxhYpVw4dOkS/LwDm7u7O3N3djSpTnz59mEqlYiqVitWvXz8vH82t3xTWh6J4enrS9bS0tGTnz59n58+fV7rZPHHv3j02f/58Nn/+fJKVP+QkIiKC7d27l929e5fdvXs3x3PPnDnD9u7dy/bu3cvq1KnDVCoVMzExYSYmJszDw4Olpqay1NRUWeXLjoULF7KFCxcyR0dHdvPmTYO0mV/evHnDevfuTb/fqlWr8vtVOvuLUTuTOmvXrmVmZmbMzMyMAWDbt29n27dvN6QIjDHGHB0daQBftGiRwdvXh+PHjzMLCwtmYWHx3kyOjDHm4+PDfHx8NCbJQ4cOGVyOGzdusBs3brAKFSpQx/r777/z8hXGnuQK5eT4+vVr1rZtW9a2bVumUqmYt7c38/b2VrrZPBMREcEiIiIUnRzzy9y5czUmx2bNmrGXL1+yly9f5vs7Fy9ezGJiYlhMTEyu5y5atIgtWrSIqVQqNm3atHy3aQiSkpLoOpmYmLDo6Oj8fpXO/iL2HAUCgUAg0CJf6VUSExNx8uRJWVN09evXjzxYBw4cSJU98umam2/c3d2z9ZAzNnxPZMCAAbQn1LdvX3h4eBhTrPeKa9euYfTo0QCk68nTePEkEIL8U7RoUarUsX//furPcsL34S9cuICmTZtSu8YiIiKCPN09PDzg7OxcoO8bNmwYQkJC6DtPnz5NBeHzm/5u1KhRVO9VV4gG92UICQmhhOjm5uaUoL2wwque8DAPKysrWb8/X3eVpaUl9u/fTwWCFy5cmNcNUJ2oD1AvX74s8PfpQ0ZGBpKTkxEcHAwAGnFVhSml2Llz56hy+ZUrV2hQX7lypVEHB32ZPn26Ruyjeno6OeAOSqVLl872eiQnJ2Pp0qXYuXMnAMmVn2/mF/aB4H1hw4YNin4/H8hbtmxJWXl2796dp6xWchYM7tKlC41VS5cuxbRp0wBI1Ymsra31GhfT09Np3Jk5cyZOnjxJYR5ubm6y5ITl4ThDhgyhcKY1a9bg1atXNPnyfNOAVKy6f//+BW5XCbjT08yZMwEAX3/9NYB3mX7kQphVBQKBQCDQIl8qh62tLX777Tdy+/34448pt2qPHj0or2VeE47fuXOHnvfr1y8/ounFtWvXyHzw119/4fbt27QiBd6tQJTKB/r8+XMAkkkmp0TJPFv+77//jtmzZ1Py5YYNG5Lpt7AVlFbPgpNT3lU5EwEcPnyYrqOPjw+++eYbOhYfH4+1a9cCAMLCwjTusbFjx1Kw9X+dEydOkEaRl/yUvBZgXFwcevXqRVpIuXLlFMmIxDNCVa9enYp6//nnn/j2228B5O7C/9lnn1FhdnXyW89x2rRpVHnj1q1blFwckLK5ZKf1MbUkAElJSThw4AAdU6lUNHaq57LNL+7u7lQH87ffftOwypUsWZJCRaZOnUpm1+zquRYGvvjiCwDAw4cPUbNmTfz666+KtJNve5y1tTUWLVoEQJoQuQoeHByMzz77DICU5NfFxYWSaeuCVxm/dOmSRmfiab3kIi4ujko7rVixQmfBTkAytS1evBgAFEtQ/ODBAwDIcU8mIiKCykFFRkaiePHitG/QsGFDReNA1YsdcxnUyW9BZfVE5HJy8eJFimecMGECJc3ODr744aYmgfSb80VFs2bNqOpCrVq16JzMzExKTM2ZPXs2AGDjxo0A3u3/jR49WpGC03Z2dgCkKvBcxlGjRtHk0q9fPzRr1oyy+bx9+xbbtm0DIA3+CQkJVHEEeHdP5rdA++jRo3H16lUAWeOiz5w5g7Nnz+r8nPrkqI25uTmNQTzmuiCoL0Sjo6M1Mgs1adIEZcqUKXAbSsN9LIYOHUoLsM6dO+O3335TLPWoMKsKBAKBQKCFbBly+Opp2rRp5NwCSCvJnJIQcw1OXQ717BoFMRvGxcVRIu8lS5ZomE45VlZW8PT0pMS/M2bMkF1r1YbnMuzRowfJ99FHH+HevXu0Ag8KCqJr0qFDBwQGBhosU4a280x+4atyNzc3RYshr1ixAt99912u55mZmaFcuXKkgVepUiW/TX6QGXL4VsPUqVPJ9Mg9QgFJc+SmcvpC9i7fr5OTE2lzSpeme/v2LeXFbd68OWXmAaScyNyykpmZSf1Nm9atW1MOUa6R5oe0tDQA78ZATk7aYU7HihQpYvDCzIWZW7dukfPN33//Tc6IBw4ckOs6GSbxeHp6OiXuPnHiBLZs2ZKlQ+miQ4cOlGjb09OzwNUmYmNj0apVK0rRpI65uTntl3711VcG91Tkbtpdu3alahLa1KhRg8w0POmuIVGv2cjhhY7VJz11lJwAc4Ob+GfMmEF7tYBUZ5Dv20ycOLHArvb/zwc5OXKePXtGg1FYWJiGF6M2PCyma9euqF27NrnVG5Kff/4ZgYGBAKBXCjjuHxEUFEQDraBwcu7cOXTt2hVJSUkApDR/YWFhAKR6ojJhnKocxuLkyZNo1KgROReMGDECTZo0ASBpDMYuyQJIYRhcUyxfvjyioqKoovm8efNQtmxZY4onyJ4PenJ8H7l27RqAd0WrufVKPY+qq6srunfvTg6DBdEWBcrCwzVat26N5ORkGrvXr1+PChUqyN2cqMohEAgEAoE+fLCao0CgIEJzFAgUhG91eXh4oHTp0hg8eDAAKOWl/98yqwoECiImR4Hgw0GYVQUCgUAg0AcxOQoEAoFAoEVuGXLeV/ORQCDIiujPAoGeCM1RIBAIBAItxOQoEAgEAoEWYnIUCAQCgUALMTkKBAKBQKCFmBwFAoFAINBCTI4CgUAgEGjxf6UFpNKR07oLAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 576x576 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_digits(instances, images_per_row=10, **options):\n",
    "    size = 28\n",
    "    images_per_row = min(len(instances), images_per_row)\n",
    "    images = [instance.reshape(size,size) for instance in instances]\n",
    "    n_rows = (len(instances) - 1) // images_per_row + 1\n",
    "    row_images = []\n",
    "    n_empty = n_rows * images_per_row - len(instances)\n",
    "    images.append(np.zeros((size, size * n_empty)))\n",
    "    for row in range(n_rows):\n",
    "        rimages = images[row * images_per_row : (row + 1) * images_per_row]\n",
    "        row_images.append(np.concatenate(rimages, axis=1))\n",
    "    image = np.concatenate(row_images, axis=0)\n",
    "    plt.imshow(image, cmap = matplotlib.cm.binary, **options)\n",
    "    plt.axis(\"off\")\n",
    "\n",
    "\n",
    "# 查看数字3和数字5的例子\n",
    "cl_a, cl_b = 3, 5\n",
    "X_aa = X_train[(y_train == cl_a) & (y_train_pred == cl_a)]\n",
    "X_ab = X_train[(y_train == cl_a) & (y_train_pred == cl_b)]\n",
    "X_ba = X_train[(y_train == cl_b) & (y_train_pred == cl_a)]\n",
    "X_bb = X_train[(y_train == cl_b) & (y_train_pred == cl_b)]\n",
    "\n",
    "plt.figure(figsize=(8,8))\n",
    "plt.subplot(221); \n",
    "plot_digits(X_aa[:25], images_per_row=5)\n",
    "plt.subplot(222); \n",
    "plot_digits(X_ab[:25], images_per_row=5)\n",
    "plt.subplot(223);\n",
    "plot_digits(X_ba[:25], images_per_row=5)\n",
    "plt.subplot(224); \n",
    "plot_digits(X_bb[:25], images_per_row=5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 左侧两个是被分类为3的图片\n",
    "# 右侧两个是被分类为5的图片\n",
    "# 大多数错误分类的图片看起来还是非常明显的错误\n",
    "# 原因：SGD是一个线性模型，它所做就是为每个像素分配一个各个类别的权重，当它看到新的图像，将加权后的像素强度汇总，从而得到一个分数进行分类\n",
    "# 数字3和5在一部分像素位上有区别，所以分类器很容易将其弄混\n",
    "# 通过上面图像，如果书写3 的连接点左移，分类器可能将其分类为数字5，这个分类器对图像位移和旋转敏感\n",
    "# 减少混淆的方法之一，就是对图像进行预处理，确保位于中心位置并且没有旋转"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多标签分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 为每个实例产生多个类别 ，例如 照片识别多个人脸\n",
    "# 分类器经过训练可以识别小红，小白，小军，一张照片 里有 小红，小白\n",
    "# 经过分类器，应该输出[1,1,0]， 是小红，是小白，不是小军\n",
    "# 输出多个二元标签的分类系统称为多标签分类系统"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "                     metric_params=None, n_jobs=None, n_neighbors=5, p=2,\n",
       "                     weights='uniform')"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "y_train_large = (y_train >= 7)\n",
    "y_train_odd = (y_train % 2 == 1)\n",
    "y_multilabel = np.c_[y_train_large, y_train_odd]\n",
    "\n",
    "knn_clf = KNeighborsClassifier()\n",
    "knn_clf.fit(X_train, y_multilabel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False,  True]])"
      ]
     },
     "execution_count": 110,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# knn支持多标签分类，不是所有的分类器都支持\n",
    "knn_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [],
   "source": [
    "# # 评估多标签分类器方法很多，方法之一就是测量每个标签的F1分数，或者其他二元分类器指标，然后简单平均\n",
    "# y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3)\n",
    "# f1_score(y_multilabel, y_train_knn_pred, average=\"macro\")\n",
    "# 0.977090"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 上面假设了所有标签都同等重要，也可以给每个标签设置一个权重（该目标标签实例的数量），设置average='weighted'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多输出分类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 例子：构建一个系统去除图片中的噪声，输入一张有噪声的图片，它将输入一张干净的数字图片，分类器输出是多个标签，一个像素一个标签，每个标签多个值0到255"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 增加噪声，目标将图片还原为原始图片 创建训练集和测试集\n",
    "noise = np.random.randint(0, 100, (len(X_train), 784))\n",
    "X_train_mod = X_train + noise\n",
    "noise = np.random.randint(0, 100, (len(X_test), 784))\n",
    "X_test_mod = X_test + noise\n",
    "y_train_mod = X_train\n",
    "y_test_mod = X_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "some_index = 5500\n",
    "plt.subplot(121);plt.imshow(X_test_mod[some_index].reshape(28, 28), cmap = matplotlib.cm.binary)\n",
    "plt.subplot(122);plt.imshow(y_test_mod[some_index].reshape(28, 28), cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn_clf.fit(X_train_mod, y_train_mod)\n",
    "clean_digit = knn_clf.predict([X_test_mod[some_index]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPgAAAD2CAYAAAD720p7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAMWElEQVR4nO3db6hc9Z3H8c9nkyvY3CJRhxiDGgPxQTEG4rTNJSlkIQYMfdB0KxbSErElkAc+UAi7RZ9YbB+sUJRCEwJSg9CKBVMsREwritFq2rnpH82DssuStM1GmGLMjQrbbPjug5xuLvfmnpl75pyZ8Zv3Cy6eOd85c74O88nvzDnn3p8jQgBy+qdRNwCgOQQcSIyAA4kRcCAxAg4ktrTpHdx4442xevXqpncDXNWmp6f/FhGtuesbD/jq1avV6XSa3g1wVbN96krrKx+i237G9tu2H6veFoAmVQq47a9KWhIRU5LW2F5bb1sA6lB1BN8i6YVi+YikzbOLtnfb7tjudLvdAdoDMIiqAV8m6XSx/IGkFbOLEXEgItoR0W615n3vBzAkVQP+kaRri+XJAV4HQIOqBnNalw/L10s6WUs3AGpV9TLZzyUdtX2zpHslbayvJQB1qTSCR8SMLp1oe0fSP0fEuTqbAlCPyje6RMRZXT6TDmAMcXIMSIyAA4kRcCAxAg4kRsCBxAg4kBgBBxIj4EBiBBxIjIADiRFwIDECDiRGwIHECDiQGAEHEiPgQGIEHEiMgAOJEXAgMQIOJEbAgcQIOJAYAQcSI+BAYgQcSIyAA4kRcCAxAg4kRsCBxBYdcNtLbf/Z9uvFz7omGgMwuCrTB98l6acR8a91NwOgXlUO0TdK+rLt39h+xnblOcYBNKtKwH8raWtEfEHShKTtc59ge7ftju1Ot9sdtEcAFVUJ+B8j4kyx3JG0du4TIuJARLQjot1qtQZqEEB1VQL+nO31tpdI+oqkP9TcE4CaVPn+/F1JP5FkSS9FxK/qbQlAXRYd8Ih4T5fOpAMYc9zoAiRGwIHECDiQGAEHEiPgQGIEHEiM+8iBmly4cKG0PjExMaROLmMEBxIj4EBiBBxIjIADiRFwIDECDiRGwIHEuA5+FTp16lRp/cSJE6X1W2+9tbR+2223LVj7+OOPS7dduXJlaf3JJ58srU9PTy9Ye/7550u33bFjR2n9k08+Ka3v2rWrtP7II48sWDtz5syCtUEwggOJEXAgMQIOJEbAgcQIOJAYAQcSI+BAYo6IRnfQbrej0+k0uo+rke1Rt3DVaTorg7A9HRHtuesZwYHECDiQGAEHEiPgQGIEHEiMgAOJEXAgMX4ffEzt379/1C0saO/evaX1devWNbbvTZs2ldbXrFnT2L4/jRjBgcT6CrjtFbaPFssTtn9h+y3bDzbbHoBB9Ay47eWSDkpaVqx6SNJ0RGyS9DXbn22wPwAD6GcEvyjpfkkzxeMtkl4olt+QNO/+V9u7bXdsd7rdbh19AqigZ8AjYiYizs1atUzS6WL5A0krrrDNgYhoR0S71WrV0ymARatyku0jSdcWy5MVXwPAEFQJ57SkzcXyekkna+sGQK2qXAc/KOmw7S9J+pykY/W2dHUo+/vdkrRnz57Kr91rnuqlS7n94WrR9wgeEVuK/56SdI+ktyRtjYiLzbQGYFCV/imPiP/W5TPpAMYUJ8iAxAg4kBgBBxIj4EBiXC9pyLvvvltab7fn3eG7KM8+++yCNS6D4R8YwYHECDiQGAEHEiPgQGIEHEiMgAOJEXAgMS6YNuSdd95p9PUfeOCBBWu7du1qdN/49GAEBxIj4EBiBBxIjIADiRFwIDECDiRGwIHEuA7ekN27d49s30899VRpffv27aX1O+64o852MEKM4EBiBBxIjIADiRFwIDECDiRGwIHECDiQGNfBGxIRpfUPP/ywtH748OHS+s6dOxesPfzww6Xbbtu2rbQ+NTVVWr/vvvtK62X3AExOTpZui3r1NYLbXmH7aLG8yvZfbb9e/LSabRFAVT1HcNvLJR2UtKxY9UVJ34uIfU02BmBw/YzgFyXdL2mmeLxR0rdtH7f9/cY6AzCwngGPiJmIODdr1cuStkj6vKQp23fN3cb2btsd251ut1tbswAWp8pZ9F9HxPmIuCjpd5LWzn1CRByIiHZEtFstvqIDo1Il4K/YXmn7M5K2SXqv5p4A1KTKZbLHJb0m6e+S9kfEn+ptCUBd3Ot67aDa7XZ0Op1G94F6HTx4sLRe9jfZJWnHjh0L1l588cUqLaEH29MRMW/See5kAxIj4EBiBBxIjIADiRFwIDECDiTGr4tinrvvvru0fvvtt5fWDx06tGDt+PHjpdtu2LChtI7FYQQHEiPgQGIEHEiMgAOJEXAgMQIOJEbAgcS4Do557rzzztL6m2++WVpftWrVgrWVK1dW6gnVMIIDiRFwIDECDiRGwIHECDiQGAEHEiPgQGJcB8eiHTt2rLR+0003LVjjOvhwMYIDiRFwIDECDiRGwIHECDiQGAEHEiPgQGJcB8c8Z8+eLa0/8cQTpfU9e/bU2Q4G0HMEt32d7ZdtH7F9yPY1tp+x/bbtx4bRJIBq+jlE3ynpBxGxTdL7kr4uaUlETElaY3ttkw0CqK7nIXpE/GjWw5akb0h6qnh8RNJmSf9Rf2sABtX3STbbU5KWS/qLpNPF6g8krbjCc3fb7tjudLvdWhoFsHh9Bdz29ZJ+KOlBSR9JurYoTV7pNSLiQES0I6LdarXq6hXAIvVzku0aST+T9J2IOCVpWpcOyyVpvaSTjXUHYCD9XCb7lqQNkh61/aikH0v6pu2bJd0raWOD/WEErr/++oG2n56erqkTDKqfk2z7JO2bvc72S5LukfTvEXGuod4ADKjSjS4RcVbSCzX3AqBm3KoKJEbAgcQIOJAYAQcSI+BAYvy6aEN6TcH79NNPl9ZPnjxZWr/lllsW29L/e/XVVytvK0lHjx4daHsMDyM4kBgBBxIj4EBiBBxIjIADiRFwIDECDiTGdfCGnDhxorS+devWIXUy3969e0vr58+fL61PTk7W2Q4axAgOJEbAgcQIOJAYAQcSI+BAYgQcSIyAA4lxHbwhEVFav3DhQml9ZmamtH769OkFa8uXLy/ddpDfJcenCyM4kBgBBxIj4EBiBBxIjIADiRFwIDECDiTGdfARmZiYKK3fcMMNA9UBqY+A275O0vOSlkj6WNL9kv5T0n8VT3koIt5trEMAlfVziL5T0g8iYpuk9yX9m6SfRsSW4odwA2OqZ8Aj4kcR8cviYUvS/0r6su3f2H7G9ryjANu7bXdsd7rdbs0tA+hX3yfZbE9JWi7pl5K2RsQXJE1I2j73uRFxICLaEdFutVq1NQtgcfo6yWb7ekk/lPQvkt6PiP8pSh1JaxvqDcCAeo7gtq+R9DNJ34mIU5Kes73e9hJJX5H0h4Z7BFBRP4fo35K0QdKjtl+XdELSc5J+L+ntiPhVc+0BGETPQ/SI2Cdp35zVjzfTDoA6cScbkBgBBxIj4EBiBBxIjIADiRFwIDECDiRGwIHECDiQGAEHEiPgQGIEHEiMgAOJEXAgMfea5nbgHdhdSadmrbpR0t8a3Wl19FYNvS1e3X3dFhHz/j5a4wGft0O7ExHtoe60T/RWDb0t3rD64hAdSIyAA4mNIuAHRrDPftFbNfS2eEPpa+jfwQEMD4foQGIEHEhsqAEv5jJ72/Zjw9xvL7aX2v6z7deLn3Wj7kmSbK+wfbRYnrD9C9tv2X5wzHpbZfuvs96/kcxXZfs62y/bPmL7kO1rxuUzt0BvjX/mhhZw21+VtCQipiStsT1OUx7dpTGbMdX2ckkHJS0rVj0kaToiNkn6mu3PjlFvX5T0vVnv36hmnJw7E+7XNT6fuZHM0jvMEXyLpBeK5SOSNg9x371sVI8ZU0fgoi7NxT5TPN6iy+/fG5JGefPG3N42Svq27eO2vz+qpq4wE+43NCafuSqz9NZhmAFfJul0sfyBpBVD3Hcvv1WPGVOHLSJmIuLcrFVj8/5dobeXdekfoM9LmrJ910gaK8yaCfcvGpP37B8WM0tvHYYZ8I8kXVssTw553738MSLOFMvjOmPqOL9/v46I8xFxUdLvNML3b9ZMuA9qzN6zOb0N5TM3zP/haV0+RFov6eQQ993Lp2HG1HF+/16xvdL2ZyRtk/TeKJq4wky4Y/OejWqW3mF+1/y5pKO2b5Z0ry59bxsX35X0E0mW9NKYzph6UNJh21+S9DlJx0bcz2yPS3pN0t8l7Y+IP42oj9kz4T4q6ceSvjkmn7m5vb2mS7P0NvqZG+qdbMXZ13skvRER7w9tx0kUH9TNkl6Z8x0YC7jaP3PcqgokNk4nagDUjIADiRFwIDECDiRGwIHE/g+RKSKMQ1o1cQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(clean_digit.reshape(28, 28), cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Type Markdown and LaTeX: 𝛼 2  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
